我想用 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/