当试图编译它时,令人惊讶的是,它给出了一个错误,因为 lambda 函数的 auto
参数已被解析为 std::string
,而编译器没有不知道如何在调用 test
时将 std::string
转换为 int
或 Widget
。
但是,我想知道为什么编译器选择了第二个 invok
函数而不是第一个,而第一个函数会成功:
#include <string>
#include <functional>
struct Widget {};
bool test(int );
bool test(Widget );
void invok(std::function<bool(int)> ); // #1
void invok(std::function<bool(std::string)> ); // #2
int main()
{
// error: unresolved overloaded function type
// invok(test);
// still error: no known conversion from std::string to
// int or Widget
invok([](auto&& x) {
return test(std::forward<decltype(x)>(x));
});
}
该示例已从 a C++ proposal 复制而来.
最佳答案
编译器没有选择#2。它正在尝试决定是否可以选择 #2。
为此,它会询问“这个通用 lambda 是否可以转换为 std::function<bool(std::string)>
”?
std::function
的转换构造函数表示“仅当它可以使用 std::string
右值调用并且结果类型可转换为 bool
时”。
编译器尝试,推断出 auto
作为std::string
,代入函数调用操作符的签名中……成功!糟糕,返回类型是 auto
,它需要一个实际类型来回答“可转换”的问题。因此它实例化函数调用运算符模板的主体以确定返回类型。
哎呀。正文对于 std::string
无效毕竟。硬错误和爆炸随之而来。
关于c++ - 使用 std::function 和通用 lambda 的函数重载:std::string 优于 int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46146346/