将函数对象传递给std :: function

时间:2017-07-21 15:50:50

标签: c++ function functor

我在使用函数对象创建std :: function的实例时遇到了一些麻烦。 (我的环境是使用Visual Studio 2015的C ++ 11。)

首先,我有一个在我的函数对象的参数列表中使用的类。这是一个简化版本,说明了要点。

class X
{
public:
    void zz(int a) const
    {
        std::cout << "X:zz, a = " << a << "." << std::endl;
    }
};

然后这是函数对象,它在operator()方法中使用X.

class Y
{
public:
    void operator()(const X& x)
    {
        x.zz(17);
    }
};

现在,我想在std :: function中包装Y的实例。函数的类型是void(const X&amp;),一个void函数,它将一个const引用作为参数。方法Y:operator()具有此签名。

void test_it
{
    X my_x;

    Y my_y;
    std::function<void(const X&)> f1(my_y);
    f1(my_x); // OK

    std::function<void(const X&)> f2(Y());
    f2(my_x); // cannot convert argument 1 from X to Y

    std::function<void(const X&)> f3(Y);
    f3(my_x); // cannot convert argument 1 from X to Y

    std::function<void(const X&)> f4(Y{});
    f4(my_x); // OK
}

第一个例子f1创建了Y,my_y的实例,并使用此实例创建了f1。这很好用。 (Y的内容被移入std :: function构造函数中的std :: function。)

第二次尝试f2在f2的构造函数中构造Y的实例。当我尝试用f2(my_x)调用它时,编译器会抱怨它无法将参数1(my_x)从X转换为Y.

第三次尝试,f3,我在f3的std :: function构造中命名函数对象类失败的方式与f2相同。

最后,f4有效。在这一个中,我使用空的初始化列表构造函数对象Y。

也许有一个简单的解释,但我不明白为什么其中两个用例不能编译。特别是f2,使用Y()和f4使用Y {},看起来几乎与我相同。

1 个答案:

答案 0 :(得分:4)

对于第二种情况,表达式Y()正在尝试定义一个函数,该函数返回Y并且不接受任何参数,并将该函数作为参数传递。这称为most vexing parse

对于第三种情况,您不能给出类型而不是函数参数。

Y的默认构造实例传递给std::function的正确方法是第4种情况。