2014-10-03 64 views
1

请有人帮助解释为什么在OS X上使用Xcode 5.1编译以下代码时出现错误。 Apple LLVM 5.1版(clang-503.0.40)(基于在LLVM 3.4svn上)。构建std :: function向量时编译器出错

#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添加到载体。我会怎么做?

谢谢。

+4

成员函数需要一个对象进行操作,他们的签名是不兼容与'void(std :: string)'在你的情况。你可以使用bind来使它工作,但你需要一个实例。 – Mat 2014-10-03 08:26:07

+0

@Mat请添加此作为答案。 – balajeerc 2014-10-03 08:30:53

+0

@Mat请你详细说明。 – ksl 2014-10-03 08:33:05

回答

1

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&)>中时,这很可能不是您想要的。而不是添加额外的第一个参数,你倒是应该与该功能将被调用为它的上下文绑定它:

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

+0

非常感谢。 – ksl 2014-10-03 12:27:43