2017-08-16 14 views
0

ここ
Can't allocate class with forward declared value in std::map member variable
私たちのコードベースに記載されているように私は同じ問題について来ました。私は、CPPにコン&デストラクタを定義するファイルをコンパイルすることを可能にすることを発見したコードと周りいじる後不完全な型::マップ

Hoever私も
...私たちのコンパイラ(MSVC 2017)はこれをコンパイルすることができ、他の例を見つけました。

test.hで:

#ifndef TEST_H 
#define TEST_H 

#include <map> 
struct Incomplete; 

class Test { 
    std::map<int, Incomplete> member; 
public: 
    Test(); 
    ~Test(); 
    int foo() { return 0; } 
}; 

#endif 

test.cppにおいて:

#include "test.h" 
struct Incomplete {}; 
Test::Test() {} 
Test::~Test() {} 

main.cppにおいて:

#include "test.h" 

int main() 
{ 
    Test test; 
    return test.foo(); 
} 

なぜ部材-STDをCPPファイルにコン&デストラクタを定義することを可能ありません:: map-variables inで使用する完全な型?それは必ずしもマップの内容を破壊するIncompleteデストラクタを呼び出す必要があるので、

+2

コンストラクタ/デストラクタ定義の上に 'struct Incomplete {}; 'を配置したので、' Incomplete'がその時点で完了するためです。 – VTT

+1

* cpp *内のcon-&destructorを何に対して定義していますか? – stijn

+0

あなたが "発見"したように見えますが、メソッド名を指定すると...デストラクタでさえ...インターフェースファイルでは、実装ファイルに定義が必要です。インタフェースのインラインメソッドは、実装時に定義を必要としません。私には適切なデザインのように見えます。 –

答えて

2

これは、クラスメンバーが完全であることをIncompleteを必要としない宣言されているので、しかしstd::mapデストラクタを呼び出すには、を行います。 (デフォルトのstd::mapコンストラクタを呼び出すとになりますが、実装によっては型が完全である必要がありますが、この仕様に仕様が必要かどうかはわかりません。 )

暗黙のctors/dtorsを生成するためにコンパイラに依存する場合、コンパイラがctorとdtorを暗黙的に生成するため、型定義が完了する必要があります。あなたがクラス定義の直後にinline Test::Test() {} inline Test::~Test() {}を書いたかのようです。 dtorは暗黙のうちに地図を破壊しようとしています。それはIncompleteの定義なしではできない格納された値に対して~Incomplete()を呼び出して地図の内容を破壊します。そして、そこには、すべてが崩壊し、あなたは間違いを起こします。あなたが後でそれらを実装しますこと、それは、したがって、何のstd::map ctorのそれらを生成しませう(Test CTOR /デストラクタの宣言を介して)コンパイラに伝える場合

しかし、/デストラクタ呼び出しがでコンパイルされますその点。

次に、あなた自身をデストラクタ/前のctorを定義するにIncompleteタイプを完了し、そうIncompleteはCTOR /デストラクタ呼び出し正常にコンパイルすることができます。 Incompleteの定義を削除すると、同じエラーが発生します。他の人が言ってきたように、あなたの代わりにマップ内の不完全な型へのポインタ/参照を格納することによって、この問題をサイドステップすることができ、


注意。不完全な型へのポインタまたは参照は、実際には完全な型です。しかし、これはすべての場合に望ましいことではないかもしれませんので、私はマップがどのように使用されるかについての詳細を知らずにその解決策を押し出すことを躊躇しています。

関連する問題