c++ - 如何在 C++ 中声明对 lambda 的引用

标签 c++ function lambda reference c++14

我想声明一个函数,该函数将具有特定原型(prototype)的函数(或 lambda)作为参数。

第一次尝试是:

#include <iostream>
using namespace std;
int test(int (&val)(int)) {
    return val(2);
}
int main() {
    cout << test([](int v){
        return v+100;
    });
    return 0;
}

女巫结果为error: invalid initialization of non-const reference of type 'int (&)(int)' from an rvalue of type 'main()::<lambda(int)>'

我尝试将指定的 const 添加到类型,但我不知 Prop 体在哪里,所以我尝试了以下适用于 GCC (-std=c++14) 的方法,但我怀疑它是非法的,因为它因 clang 失败:

int test(const auto& val) {
    return val(2);
}

我知道我可以使用模板或函数指针或 std::function 来实现相同的目的,那么请将此视为一个教学问题。我想知道在上面的第二个示例中,GCC 将 val 的类型推导为什么( int test(const auto& val) )。

template <typename F>
int test(F val) {
    return val(2);
}

int test(int val(int)) {
    return val(2);
}

int test(std::function<int(int)> val) {
    return val(2);
}

最佳答案

I want to declare a function that takes as argument a function (or lambda) with a specific prototype.

lambda 表达式生成的闭包具有唯一的匿名类型。它们也可以是通用的(即模板operator())。没有“简单”的方法来声明接受具有特定原型(prototype)的 lambda 的函数。最好的选择是使用受约束的模板参数,例如 std::is_invocable或使用某种类型删除,如 function_view .

注意:如果您的 lambda 是无捕获,它可以隐式转换为函数指针。例如

int test(int (*)(int)) { }

test([](int) -> int {});      // OK
test([i = 0](int) -> int {}); // compile-time error

I want to know what does GCC deduce the type of val to, in the second example.

int test(int val(int))

...相当于...

int test(int (*val)(int))

事实上,将它们放在同一范围内会导致重新定义错误:

int test(int val(int)) {
    return val(2);
}

int test(int (*val)(int)) {
    return val(2);
}

prog.cc:5:5: error: redefinition of 'test'
int test(int (*val)(int)) {
    ^
prog.cc:1:5: note: previous definition is here
int test(int val(int)) {
    ^

关于c++ - 如何在 C++ 中声明对 lambda 的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43539016/

相关文章:

javascript - jQuery 插件,从函数返回值

c# - 将通用方法参数转换为特定类型

c++ - lambda 类型推导失败

c++ - 将列表从 Mathematica 传递到 C++ (Mathlink)

c++ - 为什么这个类不隐式转换为指针?

c++ - 编译器独立类型

C#变量=新函数(){};

r - 如何将多变量向量值函数的输出收集到数据框中?

c++ - 如何在qt中使用QStackedwidget从一个ListWidget导航到另一个ListWidget

lambda - 用于传递成员函数的 C++0x lambda 包装器与绑定(bind)