【问题标题】:Compiler error when constructing a vector of std::function构造 std::function 向量时出现编译器错误
【发布时间】:2014-10-03 08:14:13
【问题描述】:

请有人帮忙解释为什么在 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 添加到向量中。我该怎么做?

谢谢。

【问题讨论】:

  • 成员函数需要一个对象来操作,在您的情况下,它们的签名与 void(std::string) 不兼容。您也许可以使用 bind 使其工作,但您需要一个实例。
  • @Mat 请将此添加为答案。
  • @Mat 请你详细说明一下。
  • 成员函数需要一个实例才能被调用,但是您可以将它们的指针保存在向量中。但是由于成员函数具有不同的调用签名,因此非成员函数将它们保存在同一个向量中会导致问题。

标签: c++ c++11 vector stdvector std-function


【解决方案1】:

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

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::vectorstd::function&lt;void(const std::string&amp;)&gt; 中时,这很可能不是您想要的。与其添加额外的第一个参数,不如将其与将调用该函数的上下文绑定:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    • 2019-10-30
    • 2013-04-25
    • 2014-12-08
    • 2011-03-05
    • 1970-01-01
    相关资源
    最近更新 更多