0

このコード片

#include <tuple>

struct Foo
{
    Foo(const int& value):value_(value){}

    //Foo(const Foo&)=delete; // delete copy constructor

    int value_;
};

int main()
{
    std::tuple<Foo> tup(std::move(Foo(1)));
    return 0;
}

Foo正常に動作しますが、コピー コンストラクターを削除すると、次のコンパイル エラーで失敗します: use of deleted function Foo::Foo(const Foo&)

しかし、オブジェクトを移動できることを明示的に伝えているのに、なぜコンストラクターは移動コンストラクターではなくコピー コンストラクstd::tupleターを使用するのでしょうか? インスタンスをコピーするのではなく、インスタンスを移動するようFooに強制するにはどうすればよいですか?std::tupleFoo

4

1 に答える 1

3

でも、オブジェクトが移動できることを明示的に伝えているので、

いいえ、オブジェクトを移動したいことをコンパイラに伝えています。それは同じことではありません。

コンストラクターが移動コンストラクターの代わりにコピーコンストラクstd::tupleターを使用するのはなぜですか?Foo

コピー コンストラクターを削除すると、暗黙的な移動コンストラクターが存在しないため、使用できないためです。

Foo インスタンスをコピーするのではなく、移動して std::tuple を強制的に構築するにはどうすればよいですか?

コピー コンストラクターを削除しないか、移動コンストラクターも定義します。

struct Foo
{
    Foo(const int& value):value_(value){}

    Foo(const Foo&)=delete; // delete copy constructor

    Foo(Foo&&)=default;

    int value_;
};

NBstd::moveここは完全に役に立たない:

std::tuple<Foo> tup(std::move(Foo(1)));

すべてstd::moveがその引数を右辺値にキャストしますが、一時的なFoo(1)ものはすでに右辺値であるため、右辺値を右辺値にキャストしています:役に立たない. さらに、std::moveコンパイラーがなくても、コピー省略を実行して実際の動きを最適化することができますが、それを使用するstd::moveとそれができず、コードが速くなるどころか遅くなります!

最適なコードは、最も単純なバージョンです。

std::tuple<Foo> tup(Foo(1));

またはさらに簡単です:

std::tuple<Foo> tup(1);
于 2015-09-28T15:48:17.813 に答える