5

Is std::unique_ptr<T> required to know the full definition of 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は、完全に定義する必要があります。

この推論の弱点は、クラス内イニシャライザが、クラスの宣言時にそれぞれのデータ メンバを初期化する機能を意味するという仮定です! 初期化子は宣言の一部であるため、これは直感的な自明のようです。しかし、標準で明示的にそれを述べている何かを見つけた場合、私はより快適になります。そうでなければ、それを必要としない実装ソリューションをまだ考えることができます。たとえば、コンパイラは単純にイニシャライザ式を取得し、属性の初期化が明示的に指定されていないコンストラクタにのみ適用できます。

それで、2番目のケースで A の完全な定義の必要性を暗示する標準セクション/抜粋を誰かに紹介してもらえますか? 標準のクラス内イニシャライザについてはあまり見つけられませんでした (「非静的データ メンバのブレースまたはイコール イニシャライザ」と呼ばれるものしか見つかりませんでした) が、これに関連するものは何もありませんでした。

4

1 に答える 1