可以将std :: function从右值引用移动构造到临时函子对象吗? [英] Can std::function be move-constructed from rvalue reference to a temporary functor object?

查看:340
本文介绍了可以将std :: function从右值引用移动构造到临时函子对象吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个未模板化的仿函数对象,试图将它作为 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 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆