c++ - lambda 可以用作非类型模板参数吗?

标签 c++ templates lambda c++20 non-type

下面的代码合法吗?

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:...)' .

最佳答案

Can lambdas be used as non-type template parameter?



是的,已经实现了 P0732R2 - Class types in non-type template parameters但是 clang++尚未实现。

来源:
https://en.cppreference.com/w/cpp/compiler_support

请注意,lambda 必须至少为 constexpr (默认情况下):

When this specifier is not present, the function call operator will be constexpr anyway, if it happens to satisfy all constexpr function requirements.



但是,您可以添加 constexpr在 lambda 本身而不是将其用作模板参数时获取错误。附带说明:您也可以将其指定为 consteval使其作为非类型模板参数工作。

有状态的 lambda 可以是 constexpr :
constexpr auto lmb1 = [](int i) {
    static int x = 0;
    return i*i + ++x;
};

而 lambda 通过引用捕获,或通过复制捕获 变异( mutable ),不能。通过复制 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++ - lambda 可以用作非类型模板参数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62324050/

相关文章:

c++ - 具有透明度的 MFC 图像按钮

c++ - 前向声明的类型模板可以参与模板特化吗?

C++:模板:部分特化:打印所有模板

c++ - 模板并不总是猜测初始化列表类型

c# - GC 何时可以收集挂接到事件的 Lambda?

Java 8 如何操作一个列表中的对象并将它们收集到另一个列表中?

python - 我无法从 tkinter 获取 Entry 的值,最后一个损坏了其他值

c++ - 内联函数(何时插入)?

c++ - 我的 fahrenheit-celcius 程序忽略了我的 if-else 语句,并在我每次运行该程序时将值更改为 0

c++ - 在 C++ : template argument deduction/substitution failed 中继承类时出错