可以将lambda用作非类型模板参数吗? [英] Can lambdas be used as non-type template parameter?
问题描述
以下代码合法吗?
template <auto Lambda>
struct A {};
int main () {
auto lmb = [](int i){return i*i;};
A<lmb> a;
return 0;
}
我注意到g ++可以很好地编译,而clang ++返回
错误:非类型模板参数不能具有类型'((main.cpp:...处的lambda)' c)。
I noticed that g++ compiles it fine, while clang++ returns
error: a non-type template parameter cannot have type '(lambda at main.cpp:...)'
.
推荐答案
可以将lambda用作非类型模板参数吗?
Can lambdas be used as non-type template parameter?
是,其实现已实现 P0732R2-非类型模板参数中的类类型,但 clang ++
尚未实现。
Yes, with implementations that has implemented P0732R2 - Class types in non-type template parameters but clang++
has not implemented it yet.
来源:
https://en.cppreference.com/w/cpp/compiler_support
请注意,lambda必须至少为 constexpr
(默认情况下):
Note that the lambda needs to be at least constexpr
(which it is by default):
不存在该说明符时,函数调用运算符将为
const无论如何,如果它恰好满足所有
constexpr
函数要求。
但是,您可以添加 constexpr
来获取lambda本身的错误,而不是将其用作模板参数。附带说明:您还可以将其指定为 consteval
以使其用作非类型模板参数。
You can however add constexpr
to get an error on the lambda itself instead of when using it as a template parameter. As a side note: You can also specify it to be consteval
to make it work as a non-type template parameter.
有状态lambda可以是 constexpr
:
A stateful lambda can be constexpr
:
constexpr auto lmb1 = [](int i) {
static int x = 0;
return i*i + ++x;
};
,而lambda是通过引用捕获的,或者是通过拷贝和捕获( 可变
),不能。可以通过复制 constexpr
进行捕获。
while a lambda capturing by reference, or capturing by copy and mutating (mutable
), can not. Capturing by copying a constexpr
is ok though.
通用lambda可能是 constexpr
也是:
Generic lambdas may be constexpr
too:
constexpr auto gen_lmb = []<typename T>(T& val) {
val += val;
return val;
};
template <auto Lambda>
struct A {
template<typename T>
void doit(T&& arg) {
std::cout << Lambda(arg) << '\n';
}
};
//...
A<gen_lmb> ginst;
int v = 1000;
ginst.doit(v);
ginst.doit(std::string("foo "));
std::cout << v << '\n';
2000
foo foo
2000
这篇关于可以将lambda用作非类型模板参数吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!