c++ - 使用 lambda 函数签名的函数重载

标签 c++ c++11 lambda overloading

考虑下面的例子

void foo(const std::function<int()>& f) {
    std::cout << f() << std::endl;
}

void foo(const std::function<int(int x)>& f) {
std::cout << f(5) << std::endl;
}

int main() {
    foo([](){return 3;});

    foo([](int x){return x;});
}

这不会编译,因为据说对 foo 的调用是不明确的。据我所知,这是因为 lambda 函数不是先验的 std::function 但必须转换为它并且有一个 std::function 接受任意参数的构造函数。

也许有人可以向我解释为什么有人会创建一个接受任意参数的隐式构造函数。然而,我的一个实际问题是是否有一个解决方法,它允许使用 lambda 函数的函数签名来重载函数 foo。我已经尝试过函数指针,但这没有用,因为无法将捕获的 lambda 函数转换为普通函数指针。

欢迎任何帮助。

最佳答案

根据 C++11,您的编译器是正确的。在 C++14 中,添加了一条规则,规定构造函数模板不得参与重载决议,除非参数类型实际上可以用 std::function 的参数类型调用。因此,这段代码应该可以在 C++14 中编译,但不能在 C++11 中编译。将此视为 C++11 中的疏忽。

现在,您可以通过显式转换解决此问题:

foo(std::function<int()>([](){return 3;}));

关于c++ - 使用 lambda 函数签名的函数重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27750343/

相关文章:

c++ - x86 MASM - 传递和访问二维数组

c++ - 将流运算符 >> 评估为 bool 值

c# - FK 上的 Linq 值不能为空

Javascript 双冒号 lambda

java - 如何根据重复的父对象合并列表中的子对象

c++ - SDL 不显示形状

C++字符测试;输入特定字母后如何使程序正常结束?

c++ - 在 c 和内联汇编之间传递参数

c++ - 消除 "conversion to std::vector<int>::size_type to int"警告

c++ - move 语义和 std::future