2016-04-03 7 views
0

structを転送引数で初期化したいと考えています。これは、デストラクタを宣言し、構造体を関数から返そうとするときを除いて、コンパイルされて正常に動作します(コピーコンストラクタを必要とすると思います)。宣言子と引数転送コンストラクタを含む構造体の暗黙的コピー

#include <utility> 

struct Foo 
{ 
    int val; 

    Foo(int val) : val(val) 
    { 
    } 
}; 

struct FooContainer 
{ 
    Foo member; 

    template<typename... Args> 
    FooContainer(Args&&... args) : 
     member(std::forward<Args>(args)...) 
    {} 

    ~FooContainer() {} 
}; 

FooContainer getFooContainer() 
{ 
    FooContainer retval(0); 
    return retval; 
} 

int main() {} 

コンパイルエラーがある:

example.cc: In constructor ‘FooContainer::FooContainer(Args&& ...) [with Args = FooContainer&]’: 
example.cc:27: instantiated from here 
example.cc:18: error: no matching function for call to ‘Foo::Foo(FooContainer&)’ 
example.cc:7: note: candidates are: Foo::Foo(int) 
example.cc:4: note:     Foo::Foo(const Foo&) 

それはFooContainerのためにコピーコンストラクタを生成しようとしているように見えますが、それはFooのを初期化する方法を持っていないため失敗します。それでも、私がFooContainerのコンストラクタまたはデストラクタを削除しても、それは正常にコンパイルされます。

* on http://cpp.sh/とGCC 4.9.2とにかく。 Ubuntuのg ++​​ 4.4.3では、デストラクタが宣言されていなくても同じエラーが返されます。

+1

コンパイラエラーを見ると、コンパイラがいるかどうか知らないかのように、それが見えますFooまたは 'Foo(int val)'コンストラクタのコピーコンストラクタを呼び出すことができます。 'Foo(int val)'を 'explicit'にしてみてください。 – user3147395

+0

私はそれを行い、何も変更しませんでしたが、 'FooContainer'コンストラクタを' explicit'にしました。ありがとう!今私のプログラムの中に私のすべての問題を修正するのか、それともいくつかの問題を修正するかどうかを見てみましょう... –

答えて

1

これはなぜ発生するのですか(標準的なエキスパートができます)、実際にはユーザー定義のデストラクタを定義したために問題が発生しています。

(あなたは右、とにかくルールのゼロを使用したい?)それを削除し、問題が消える

をあなたはデストラクタを持っている必要があり、交換、その後、何らかの理由ですぐにそれをリファクタリングすることができない場合移動コンストラクタ(デストラクタを提供することによって暗黙的に削除される)もそれを解決します。

ソリューション1から0の使用ルール:

#include <utility> 

struct Foo 
{ 
    int val; 

    Foo(int val) : val(val) 
    { 
    } 
}; 

struct FooContainer 
{ 
    Foo member; 

    template<typename... Args> 
    FooContainer(Args&&... args) : 
    member(std::forward<Args>(args)...) 
    {} 

// ~FooContainer() {} 
}; 

FooContainer getFooContainer() 
{ 
    FooContainer retval(0); 
    return retval; 
} 

int main() {} 

ソリューション2から5までの使用ルール:

#include <utility> 

struct Foo 
{ 
    int val; 

    Foo(int val) : val(val) 
    { 
    } 
}; 

struct FooContainer 
{ 
    Foo member; 

    template<typename... Args> 
    FooContainer(Args&&... args) : 
    member(std::forward<Args>(args)...) 
    {} 

    FooContainer(const FooContainer&) = default; 
    FooContainer(FooContainer&&) = default; 
    FooContainer& operator=(const FooContainer&) = default; 
    FooContainer& operator=(FooContainer&&) = default; 

    ~FooContainer() {} 
}; 

FooContainer getFooContainer() 
{ 
    FooContainer retval(0); 
    return retval; 
} 

int main() {} 
関連する問題