我以一种令我挠头的方式打破了一些代码。以下演示了该问题( http://ideone.com/TsRPcx 的完整代码):
#include <functional>
typedef std::function<bool()> BoolCallback;
typedef std::function<void()> VoidCallback;
// Support two types of callback
void scan( BoolCallback func ) {}
void scan( VoidCallback func ) {}
int main( int argc, char* argv[] )
{
scan( [] {} ); // Original, unambiguous.
scan( [] { return true; } ); // New, broken call. Ambiguous.
}
使用gcc 5.1,第一个调用编译好,但第二个调用call of overloaded ‘scan(main(int, char**)::<lambda()>)’ is ambiguous
。所以第一个问题是,这些调用中的一个如何可以正常,另一个是不明确的?
认为这可能与我正在使用的lambda表达式有关,我尝试了一些其他方法(扰乱警报:它们都产生相同的结果):
scan( []() -> void {} ); // Unambiguous
scan( []() -> bool { return true; } ); // Ambiguous
auto vcb = []() -> void {};
auto bcb = []() -> bool { return true; };
scan( vcb ); // Unambiguous
scan( bcb ); // Ambiguous
extern void voidCallback();
extern bool boolCallback();
scan( voidCallback ); // Unambiguous
scan( boolCallback ); // Ambiguous, so it's not the lambdas
scan( (VoidCallback)vcb ); // Unambiguous
scan( (BoolCallback)bcb ); // Eureka!
显式强制转换可以解决歧义,将上面的bcb
明确声明为BoolCallback
而不是auto
(未显示)。
最后,我尝试更改回调类型:
typedef void (*VoidCallback)();
typedef bool (*BoolCallback)();
嗯...这适用于上述所有情况。它不是解决方案,因为这是需要std::function
提供的通用性的库代码,但它很有趣。
有人可以解释为什么这对于没有返回任何值的std::function
对象或者在任何情况下对于原始函数指针来说都是明确的,但是否则是不明确的?