构造std::函数的向量时出现编译器错误

Compiler error when constructing a vector of std::function

本文关键字:编译器 错误 向量 std 函数 构造      更新时间:2023-10-16

请有人帮助解释为什么我在OS X上使用Xcode 5.1编译以下代码时出错。Apple LLVM版本5.1(clang-503.0.40)(基于LLVM 3.4svn)。

#include <vector>
#include <functional>
void func1(const std::string& value)
{
    // ...
}
void func2(const std::string& value, int min, int max)
{
    // ...
}
class X
{
public:
    void x1(const std::string& value)
    {
        // ...
    }
    void x2(const std::string& value, int min, int max)
    {
        // ...
    }
};
const std::vector<std::function<void(std::string)>> functions
{
    func1,
    std::bind(func2, std::placeholders::_1, 5, 6),
    std::mem_fn(&X::x1),                                // compiler error
};

报告的错误为:

no matching constructor for initialization of 'const std::vector<std::function<void (std::string)> >'
const std::vector<std::function<void(std::string)>> functions

此外,我想把X::x2加到向量上。我该怎么做?

谢谢。

std::mem_fn所做的是,它返回一些未指定的对象,该对象可使用与传入的成员函数或成员变量所属类型相同的指针或引用类型(甚至智能指针类型)的附加第一个参数调用(所有其他参数都被转发)。这意味着您可以将该对象存储在如下所示的函数包装器中:

std::function<void(X*,const std::string&)> f = std::mem_fn(&X::x1);

然后用一个实际的参数调用它:

X x{};
f(&x, "foo"); // or std::mem_fn(&X::x1)(&x, "foo");

与相同

(&x)->x1("foo");

换句话说,在将可调用对象存储在std::function<void(const std::string&)>std::vector中时,这很可能不是您想要的。与其添加额外的第一个参数,不如将其与将调用该函数的上下文绑定:

X x{}; // object in context of which the function will be called
const std::vector<std::function<void(std::string)>> functions
{
    func1,
    std::bind(func2, std::placeholders::_1, 5, 6),
    std::bind(&X::x1, &x, std::placeholders::_1),
//  ~~~~~~~~^ ~~~~~^  ~^            ~~~~~~~~~~^
//     bind  function with object x and actual argument to be forwarded
};

DEMO