2010-08-30 133 views
2

我必须将函数传递到指针。为此,我使用boost :: function。捕获指针的函数对于不同的签名来说是过载的。例如:指针功能

void Foo(boost::function<int()>) { ... } 
void Foo(boost::function<float()>) { ... } 
void Foo(boost::function<double()>) { ... } 

现在我想通过一些类方法的指针有:

class test 
{ 
    public: 
     float toCall() { }; 
}; 

class Wrapper 
{ 
    Wrapper() { 
    test obj; 
    Foo(boost::bind(&test::toCall, this)); 
    } 
}; 


error: no matching function for call to ‘Foo(boost::_bi::bind_t<float, boost::_mfi::mf0<float, test>, boost::_bi::list1<boost::_bi::value<Wrapper*> > >)’ 
    note: candidates are: Foo(boost::function<float()>&) 

回答

6

Nonono这不能工作。因为boost::function<...>有一个模板化的构造函数来接受任何和所有类型。稍后将检查与呼叫签名的兼容性。重载解析无法解决此问题。

此外,我想你想通过&obj而不是this。尝试显式转换:

Foo(boost::function<float()>(boost::bind(&test::toCall, &obj))); 

这是完全丑陋的,但这样你可能想引入一个typedef

void Foo(FloatHandler) { ... } 
... 
FloatHandler f(boost::bind(&test::toCall, &obj)); 
Foo(f); 

还是少不了你可以做Foo接受随便什么可调用类型T的模板。我怀疑这可能是最简单的,因为在一般情况下,我怀疑你不知道你需要投什么boost::function<...>。而那些想要返回std::complex<>的人呢?所以...

template<typename T> 
void Foo(T) { ... } 
... 
Foo(boost::bind(&test::toCall, &obj)); 

希望这会有所帮助。

1

boost::bind不返回boost::function对象。它返回一个未指定的对象类型,它可以用作具有相应参数个数的函子。

虽然boost::function可以根据boost::bind的结果进行转换构造,但是对于C++来说,在这种情况下重载分辨率“太复杂”。 (删除了我的坏例子,但没有真正说明正确的问题)。

+0

对于助推功能,场景甚至比这更邪恶。它就像'template struct A {template A(U); };'现在,* *看起来不能解决我的问题xD请注意,如果只有一个函数,你可以转换。难点是*比较*两个这样的转换序列。在boost :: function的情况下,这是完全不可能的,在你的情况下,它可能是可能的,但它对于over-res来说太复杂了。 – 2010-08-30 23:42:50

+0

@Johannes Schaub:你说得对。我的例子说明了一个完全不同的问题:歧义而不是“不可解决”:) – AnT 2010-08-30 23:47:36

2

在线路

Foo(boost::bind(&test::toCall, this)); 

thisWrapper类型。但绑定无法在其上找到toCall方法。

这里有一个固定的后续版本(完整的,汇编了G ++ 4.3.2),这可能是你想要做什么:

#include <boost/bind.hpp> 
#include <boost/function.hpp> 

void Foo(boost::function<int()>) {} 
void Foo(boost::function<float()>) {} 
void Foo(boost::function<double()>) {} 

struct test { 
    float toCall() {return 0.0f;} 
}; 

int main(int,char**) { 
    test obj; 
    boost::function<float()> tgt=boost::bind(&test::toCall,obj); 
    Foo(tgt); 
    return 0; 
} 

由于AndreyT的回答指出,绑定的返回类型。 ..有点奇怪,因此显式强制适当的函数类型。