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() {}

コンパイラ エラーは次のとおりです。

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正常にコンパイルされます.* なぜこれを行うのですか?

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

4

1 に答える 1

1

なぜこれが起こるのか正確にはわかりませんが(標準の専門家ならわかるでしょう)、ユーザー定義のデストラクタを定義したために実際に問題が発生します。

それを削除すると、問題は解決します (とにかくゼロのルールを使用したいですか?)

デストラクタが必要で、何らかの理由でリファクタリングできない場合は、(デストラクタを提供することで暗黙的に削除した) move-constructor を置き換えることでも解決されます。

解決策 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() {}
于 2016-04-04T00:21:23.717 に答える