c++ - 无法使用默认参数初始化 lambda 成员变量

标签 c++ templates lambda default-arguments

我想用 c++17 编译下面的代码,这样我就可以传递任何具有特定签名 int(int) 的函数 (lambda),同时也允许默认值论据:

template <class F = int(int)> // for deduction
struct A{
        A(F f = [] (int x){return x;}) : f_{f} {}

        F f_;
};

int main() {
        A work([](int x){return x + 1;});
        A not_work; // compile error.
}

但是,clang 会发出错误:

a.cpp:6:4: error: data member instantiated with function type 'int (int)'
        F f_;
          ^
a.cpp:11:4: note: in instantiation of template class 'A<int (int)>' requested here
        A not_work;
          ^

我不明白为什么当我传递 lambda 时可以初始化成员 f_ 而默认的 lambda 参数却不能?

同时,有没有更好的方法来做到这一点?

最佳答案

正如错误消息所述,您不能声明具有类似 int(int) 的函数类型的数据成员。 .

将 lambda 传递给构造函数时,模板参数 F将被 CTAD (since C++17) 推导为 lambda 闭包类型;当什么都不传递时F将使用默认参数 int(int)和数据成员 f_的类型将是 int(int)也会导致错误。

您可以使用函数指针类型(lambdas 没有捕获可以隐式转换为函数指针)或 std::function<int(int)> 。例如

template <class F = int(*)(int)> // for deduction
struct A{
        A(F f = [] (int x){return x;}) : f_{f} {}

        F f_;
};

或者

template <class F = std::function<int(int)>> // for deduction
struct A{
        A(F f = [] (int x){return x;}) : f_{f} {}

        F f_;
};

关于c++ - 无法使用默认参数初始化 lambda 成员变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70178477/

相关文章:

c++ - 如何强制重新编译 Makefile 中的单个文件?

c++ - 错误: expected class-name before ‘{’ token with templates

python - Lambda 函数要求输入两次,

c++ - 良好的哈希函数可以从数组中删除重复项

C++ - "Stack automatic"是什么意思?

c++ - 在模板中使用模板实例类型

c++ - 具有条件类型名的模板类

c# - Lambda 分配局部变量

c++ - 我的 Boost Phoenix lambda 有什么问题?

c++ - 类内的多个线程访问数据