可以将std :: function从右值引用移动构造到临时函子对象吗? [英] Can std::function be move-constructed from rvalue reference to a temporary functor object?
问题描述
我有一个未模板化的仿函数对象,试图将它作为 std :: function
存储在另一个对象中。该对象确实是重量级的,因此标记为不可复制,但确实具有move构造函数。但是,尝试从临时构造函数构造或分配std :: function失败。
I have an untemplated functor object that I'm trying to store as a std::function
inside another object. This object is really heavyweight, so it's marked as uncopyable, but it does have a move constructor. However, trying to construct a std::function, or assign it, from a temporary constructor fails.
以下是引发错误的最小示例。
Here is a minimal example to provoke the error.
// 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();
}
在一个更简单的构造中,我只是在做一个局部函数,我也收到错误消息:
In an even simpler construction, where I'm just making a local function, I also get the error:
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应该作为右值传递给函数构造函数。但是编译器想要复制它们。
So far as I can tell, in all of these cases, a temporary ExampleTest ought to be passed to the function constructor as an rvalue. Yet the compiler wants to copy them.
有什么用?是否可以将不可复制(但可移动复制)的仿函数对象传递给std :: function构造函数?有使用指针等的解决方法,但我想了解这里发生了什么。
What gives? Is it possible to pass uncopyable (but move-copyable) functor objects to a std::function constructor? There are workarounds with pointers and so on, but I want to understand what is going on here.
上面的特定错误来自Visual Studio 2012和CTP C ++ 11个补丁。 GCC 4.8和Clang 3也因自身的错误消息而掉线。
The specific errors above are from Visual Studio 2012 with the CTP C++11 patch. GCC 4.8 and Clang 3 also fall down, with their own error messages.
推荐答案
确实是重量级的,因此标记为不可复制,但是它确实具有move构造函数。
This object is really heavyweight, so it's marked as uncopyable, but it does have a move constructor.
如果仿函数是不可复制的,则它不符合与 std一起使用的必要要求: :function
。 C ++ 11标准的20.8.11.2.1 / 7段指定:
If a functor is non-copyable, it does not meet the necessary requirements for being used with std::function
. Paragraph 20.8.11.2.1/7 of the C++11 Standard specifies:
template<class F> function(F f);
template <class F, class A> function(allocator_arg_t, const A& a, F f);
7 要求: F
为 CopyConstructible
。对于参数类型 ArgTypes $ c $,
f
应该是 Callable
(20.8.11.2) c>
,然后返回类型 R
。 A
的副本构造函数和析构函数不得抛出异常。
7 Requires: F
shall be CopyConstructible
. f
shall be Callable
(20.8.11.2) for argument types ArgTypes
and return type R
. The copy constructor and destructor of A
shall not throw exceptions.
这篇关于可以将std :: function从右值引用移动构造到临时函子对象吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!