将函数对象传递给 std::function
Passing a function object to std::function
我在使用函数对象创建 std::function 的实例时遇到了一些麻烦。 (我的环境是 C++ 11,使用 Visual Studio 2015。)
首先,我有一个 class 用于我的函数对象的参数列表。这是说明要点的简化版本。
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);
}
};
现在,我想将 Y 的实例包装在 std::function 中。该函数的类型是 void(const X&),一个以对 X 的 const 引用作为参数的 void 函数。方法 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构造中只是将函数对象命名为class,失败的方式与f2相同。
终于,f4 起作用了。在这一个中,我使用一个空的初始化列表构造函数对象 Y。
也许有一个简单的解释,但我不明白为什么其中两个用例无法编译。特别是 f2,使用 Y(),f4 使用 Y{},对我来说几乎是一样的。
对于第二种情况,表达式 Y()
试图定义一个 returns 和 Y
并且不带参数的函数,并将该函数作为参数传递。这被称为 most vexing parse.
对于第三种情况,您不能给出类型而不是函数参数。
将 Y
的默认构造实例传递给 std::function
的正确方法是第 4 种情况。
我在使用函数对象创建 std::function 的实例时遇到了一些麻烦。 (我的环境是 C++ 11,使用 Visual Studio 2015。)
首先,我有一个 class 用于我的函数对象的参数列表。这是说明要点的简化版本。
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);
}
};
现在,我想将 Y 的实例包装在 std::function 中。该函数的类型是 void(const X&),一个以对 X 的 const 引用作为参数的 void 函数。方法 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构造中只是将函数对象命名为class,失败的方式与f2相同。
终于,f4 起作用了。在这一个中,我使用一个空的初始化列表构造函数对象 Y。
也许有一个简单的解释,但我不明白为什么其中两个用例无法编译。特别是 f2,使用 Y(),f4 使用 Y{},对我来说几乎是一样的。
对于第二种情况,表达式 Y()
试图定义一个 returns 和 Y
并且不带参数的函数,并将该函数作为参数传递。这被称为 most vexing parse.
对于第三种情况,您不能给出类型而不是函数参数。
将 Y
的默认构造实例传递给 std::function
的正确方法是第 4 种情况。