私は、別のオブジェクトの内部にstd::function
として格納しようとしている、テンプレートのないファンクタオブジェクトを持っています。このオブジェクトは本当にヘビーなので、コピー不可能とマークされていますが、移動コンストラクタはあります。しかし、一時的なコンストラクタからstd :: functionを構築しようとしたり、それを代入しようとすると失敗します。std :: functionをrvalue参照から一時的なファンクタオブジェクトに移動構築することはできますか?
ここでは、エラーを引き起こす最小限の例を示します。さらに簡単な工事、私はローカル関数を作ってるんだところ、私もエラーを取得するには
// pretend this is a really heavyweight functor that can't be copied.
struct ExampleTest
{
int x;
int operator()(void) const {return x*2;}
ExampleTest() :x(0){}
ExampleTest(int a) :x(a){}
// allow move
ExampleTest(ExampleTest &&other) :x(other.x) {};
private: // disallow copy, assignment
ExampleTest(const ExampleTest &other);
void operator=(const ExampleTest &other);
};
// this sometimes stores really big functors and other times stores tiny lambdas.
struct ExampleContainer
{
ExampleContainer(int);
std::function<int(void)> funct;
};
/******** ERROR:
Compiler error: 'ExampleTest::ExampleTest' : cannot access private member
declared in class 'ExampleTest'
******************/
ExampleContainer::ExampleContainer(int x)
: funct(ExampleTest(x))
{}
/******** ERROR:
Compiler error: 'ExampleTest::ExampleTest' : cannot access private member
declared in class 'ExampleTest'
******************/
int SetExample(ExampleContainer *container)
{
container->funct = ExampleTest();
return container->funct();
}
:
int ContrivedExample()
{
// extra parens to sidestep most vexing parse
std::function<int()> zug((ExampleTest()));
/*** ERROR: 'ExampleTest::ExampleTest' : cannot access private member
declared in class 'ExampleTest' */
int troz = zug() ;
return troz;
}
これまでのところ、私が言うことができるように、これらすべての場合で、一時的なExampleTestは、右辺値として関数コンストラクタに渡されるべきです。しかし、コンパイラはそれらをコピーしたい。
何がありますか?コピーできない(しかしコピー可能な)ファンクタオブジェクトをstd :: functionコンストラクタに渡すことは可能ですか?ポインタなどの回避策がありますが、ここで何が起こっているのか理解したいと思います。
上記の特定のエラーは、CTP C++ 11パッチを適用したVisual Studio 2012のものです。 GCC 4.8とClang 3も落ち込み、独自のエラーメッセージが表示されます。
C++ 11を使用している場合は、private copy-ctorおよびassignment-opの代わりに中括弧初期化 'ExampleTest {}'と '= delete'を使用してください。 – dyp
移譲代入演算子を追加するとどうなりますか? –
@DyP初期化子リストの構築や '= delete'構文を確実にサポートするために私がアクセスできるコンパイラはありません。 – Crashworks