将可调用对象传递给采用std :: function的构造函数

时间:2018-08-06 19:35:17

标签: c++ functional-programming c++14 c++17 move-semantics

我在传递带有重载运算符bool的可调用对象时很挣扎。它还具有unique_ptr的数据,因此复制被禁用。 我正在尝试将这样的对象传递给另一个构造函数采用std :: function的对象,我认为这是完全合法的。

查看示例:

#include <functional>
#include <memory>
#include <utility>

using namespace std;

class invoker
{
    public:
        invoker(function<bool(void)> fnc_):
            fnc { move(fnc_) }
        {}
        ~invoker() = default;    
    private:
        function<bool(void)> fnc;
};

class action
{
  public:
    action() = default;
    ~action() = default;
    action(const action& rhs) = delete;
    action& operator=(const action& rhs) = delete;

    action(action&& rhs):
        data { move(rhs.data)}
    {
    }
    action& operator=(action&& rhs)
    {
        if (this != &rhs)
        {
            data = std::move(rhs.data);
        }
    }

    bool operator()()
    {
        return true;
    }

  private:    
    unique_ptr<int> data;
};

int main()
{
    auto runner = std::make_unique<invoker>(std::move(action {}));
    //unique_ptr<invoker> runner(new invoker(action() ));

    return 0;
}

为什么编译器会抱怨?

> /usr/include/c++/5/functional:1710:34: error: use of deleted function
> 'action::action(const action&)'
>     __dest._M_access<_Functor*>() =

1 个答案:

答案 0 :(得分:2)

您将std::function 按值传递给构造函数。这意味着必须复制。由于删除了复制构造函数,因此它的内容(如包装的action对象)不能被复制。

action对象无论如何都不能复制,因为它包含不可复制的成员(data成员变量)。您无需显式删除copy-constructor,因为该成员的存在,它还是会被删除。

解决此问题的最佳选择是使用lambda作为参数,而不是创建(临时)action对象。