我有一个未模板化的仿函数对象,我试图将其存储为std::function
另一个对象内部。这个对象真的很重量级,所以它被标记为不可复制,但它确实有一个移动构造函数。但是,尝试从临时构造函数构造或分配 std::function 会失败。
这是引发错误的最小示例。
// 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 也失败了,并带有自己的错误消息。