【发布时间】:2022-01-23 23:23:05
【问题描述】:
考虑这个简单的示例代码:
#include <functional>
#include <iostream>
void f(bool _switch) {
std::cout << "Nothing really" << std::endl;
}
void f(std::function<double (int)> _f) {
std::cout << "Nothing really, too" << std::endl;
}
int main ( int argc, char* argv[] ) {
f([](int _idx){ return 7.9;});
return 0;
}
编译失败:
$ g++ --std=c++11 main.cpp
main.cpp: In function ‘int main(int, char**)’:
main.cpp:15:33: error: call of overloaded ‘f(main(int, char**)::<lambda(int)>)’ is ambiguous
main.cpp:15:33: note: candidates are:
main.cpp:6:6: note: void f(bool)
main.cpp:10:6: note: void f(std::function<double(int)>)
但是,如果我用引用参数替换第二个函数,它编译得很好。如果它被 const 引用替换,它再次失败。
所以我对这个例子有一些疑问:
- 为什么 lambda 函数首先可以隐式转换为
bool? - 为什么采用 std::function 引用可以解决歧义?
- 对我来说最重要的是,如何避免这个问题?我需要第二个函数来获取(a 的副本)std::function 或对它的 const 引用。
【问题讨论】:
-
重载采用
std::function的函数目前不是一个好主意。在 C++11 中有一个std::function的贪婪构造函数模板,它不需要(SFINAE-)拒绝“无效”类型。也就是说,第二个重载可以匹配任何类型。不过,它随后会被列为用户定义的转化。
标签: c++ c++11 lambda overloading