可以向前声明一个采用具有默认值的不完整类型向量的函数吗?

问题描述 投票:0回答:1

下面的代码片段演示了我最近在程序中遇到的一些实际问题:

#include<vector>

class A;

void f( const std::vector<A> & = {} );

有一个不完整的类

A
,以及一个采用
vector
中的
A
且默认值为空的函数声明。而且该函数甚至没有在任何地方被调用。

它在 GCC 和 Clang 14 中工作正常,但从 Clang 15 开始出现错误:

In file included from <source>:1:
/opt/compiler-explorer/clang-15.0.0/bin/../include/c++/v1/vector:540:52: error: arithmetic on a pointer to an incomplete type 'A'
        {return static_cast<size_type>(__end_cap() - this->__begin_);}
                                       ~~~~~~~~~~~ ^
/opt/compiler-explorer/clang-15.0.0/bin/../include/c++/v1/vector:760:56: note: in instantiation of member function 'std::vector<A>::capacity' requested here
      __annotate_contiguous_container(data(), data() + capacity(),
                                                       ^
/opt/compiler-explorer/clang-15.0.0/bin/../include/c++/v1/vector:431:7: note: in instantiation of member function 'std::vector<A>::__annotate_delete' requested here
      __annotate_delete();
      ^
<source>:5:32: note: in instantiation of member function 'std::vector<A>::~vector' requested here
void f( const std::vector<A> & = {} );
                               ^
<source>:3:7: note: forward declaration of 'A'
class A;
      ^
c++ language-lawyer stdvector forward-declaration incomplete-type
1个回答
0
投票

是的,Clang 拒绝该程序是正确的。根据 vector.overview#4

如果分配器满足分配器完整性要求,则在实例化

T
时可以使用不完整类型
vector
T
应在引用
vector
所产生的专业化的任何成员之前完成。

在默认参数中,您在

vector<A>
完成之前引用
A
的构造函数,因此程序格式不正确。

这里有一个 bug 报告(因无效而关闭)显示了类似的情况。底部的评论表明了为什么这可能在 Clang-15 中发生了变化。

libc++14 和 libc++15 之间的变化可能是向量移动构造函数变成了 constexpr,因此现在它被更早实例化。

© www.soinside.com 2019 - 2024. All rights reserved.