我已阅读是否需要 std::unique_ptr<T> 才能知道 T 的完整定义?和unique_ptr的前向声明?,但我的问题更具体。
以下编译:
// Compile with $ g++ -std=c++11 -c <filename>
#include <memory>
class A; // fwd declaration
class AUser
{
AUser(); // defined elsewhere
~AUser(); // defined elsewhere
std::unique_ptr<A> m_a;
};
以下没有:
// Compile with $ g++ -std=c++11 -c <filename>
#include <memory>
class A; // fwd declaration
class AUser
{
AUser(); // defined elsewhere
~AUser(); // defined elsewhere
std::unique_ptr<A> m_a{nullptr};
};
错误
$ g++ -std=c++11 -c fwd_decl_u_ptr.cpp
In file included from /usr/include/c++/4.7/memory:86:0,
from fwd_decl_u_ptr.cpp:3:
/usr/include/c++/4.7/bits/unique_ptr.h: In instantiation of ‘void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = A]’:
/usr/include/c++/4.7/bits/unique_ptr.h:173:4: required from ‘std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = A; _Dp = std::default_delete<A>]’
fwd_decl_u_ptr.cpp:9:33: required from here
/usr/include/c++/4.7/bits/unique_ptr.h:63:14: error: invalid application of ‘sizeof’ to incomplete type ‘A’
编辑:据我了解,这里发生的是类内初始化程序意味着能够unique_ptr<A>
在AUser
. 由于类型unique_ptr<A>
实际上是unique_ptr<A, default_delete<A>>
,能够初始化它意味着能够初始化default_delete<A>
。而且,为此,A
必须完全定义。
这个推理中的薄弱环节是假设类内初始化器意味着在类声明时初始化相应数据成员的能力!这似乎是一个直观的不言而喻,因为初始化程序是声明的一部分。但是,如果我在标准中找到明确说明的内容,我会更舒服。否则我仍然可以想到不需要它的实施解决方案。例如,编译器可以简单地采用初始化表达式并将其仅应用于未明确给出属性初始化的构造函数。
那么,任何人都可以向我推荐一个标准部分/摘录,这意味着在第二种情况下需要完整定义 A 吗?我在标准中没有找到太多关于类内初始化器的信息(只发现它们被称为“非静态数据成员的大括号或相等初始化器”),但与此无关。