c++ - 可以将 lambdas 用作非类型模板参数吗?
问题描述
下面的代码合法吗?
template <auto Lambda>
struct A {};
int main () {
auto lmb = [](int i){return i*i;};
A<lmb> a;
return 0;
}
我注意到 g++ 编译得很好,而 clang++ 返回
error: a non-type template parameter cannot have type '(lambda at main.cpp:...)'
.
解决方案
可以将 lambdas 用作非类型模板参数吗?
是的,使用已实现P0732R2 - 非类型模板参数中的类类型但clang++
尚未实现它的实现。
来源: https ://en.cppreference.com/w/cpp/compiler_support
请注意,lambda 至少需要constexpr
(默认情况下):
当此说明符不存在时,函数调用运算符
constexpr
无论如何都会存在,如果它恰好满足所有constexpr
函数要求。
但是,您可以添加constexpr
以获取 lambda 本身的错误,而不是在将其用作模板参数时。附带说明:您还可以将其指定consteval
为使其作为非类型模板参数工作。
有状态的 lambda 可以是constexpr
:
constexpr auto lmb1 = [](int i) {
static int x = 0;
return i*i + ++x;
};
而通过引用捕获或通过复制和变异 ( mutable
) 捕获的 lambda 则不能。不过,通过复制 a 来捕获是可以的constexpr
。
通用 lambda 也可能是constexpr
:
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
推荐阅读
- c# - 如何耗尽 ASP.NET 工作线程以显示异步等待模式的重要性
- loader - 我们如何在 div 的清晰框架中添加加载器,因为我们可以添加 Datagrid 属性 [clrDgLoading]="loading" 以添加加载器
- tcp - 了解 TCP 慢启动
- tensorflow - 在 TPU 上训练模型后预测单张图像的值
- arrays - 我可以只用一个类型而不是一个具体变量来获得一个 Rust 数组的长度吗?
- javascript - RangeError:当数据为 100k 时,jsreport 中的字符串长度无效
- android - 如何在目标图像上完全拟合 AR ViewRenderable?
- javascript - 我们能否知道所有网站的输入标签的用户名/密码的可能 id/name 属性值?
- rest - 从 Delphi REST 服务器返回具有计算字段的数据集
- javascript - 做了react.js,Chrome扩展失去焦点,如何强制弹窗强制重新渲染