2011-01-21 62 views
5

我的问题代码:C++超载:字符串常量与升压::功能歧义

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

void func (const std::string&) {} 
void func (const boost::function<void()>&) {} 

int main() { 
    func (main); // good 
    func ("bad"); 
    return 0; 
} 

=>

error: call of overloaded ‘func(const char [4])’ is ambiguous 
overload.cpp:4: note: candidates are: void func(const std::string&) 
overload.cpp:5: note:     void func(const boost::function<void()()>&) 

我知道我可以通过显式调用FUNC(字符串(解决这个“坏“));或者通过提供一个func(const char *),但我想知道是否有一种方法来保持调用者方面的例子,并且不会引入更多的重载。

也许用boost :: enable_if做些什么? 感谢您的任何提示。

+0

你真的认为原因是需要`boost :: function`的重载,你有没有尝试编译没有超载?这会工作吗? – Nim 2011-01-21 09:56:33

+1

是由boost :: function引起的。我发布的例子重现了整个情况。 – denis 2011-01-21 10:04:52

+0

是啊 - 没有测试之前询问,只是有点困惑,这是这种情况 - 看起来像它是..嗯..缺少提供超负荷的一切,不知道有一个整洁的解决方案... – Nim 2011-01-21 10:18:43

回答

4

你不能轻易解决这个问题。 boost::function<>std::function<>不支持仅可由f()调用的函数,但也指向由(secondArg.*firstArg)()和数据成员调用的成员,因此它们的构造函数基本上都唾手可得,然后决定如何处理该类型。

写这样一个SFINAE测试类可以防止隐式转换(我甚至不确定它是否完全可能,因为标准库没有这样做,这一点也不重要。一些原因)。请记住,由于许多不同的属性,类型可能是可调用的 - 它可能具有函数指针类型等的转换函数pp。编写一个可以使其工作的SFINAE类意味着在某些情况下拒绝隐式转换并接受隐式转换其他案例基于真正不明显的属性。

如果你想避免这种不明确的地方,我会尝试只选择一个不同的函数名称,或者如果它是一次性问题,在来电方进行投射。

0

补充一点:

void func (const char *s) { func(string(s)); } 

更新

template<class A0, ...> 
void func (const A0 &a0, ...) { 
    func(argize(a0), ...); // convert chars to strig, otherwise jut pass 
}