[英]Why cannot I use labmda as non-type template parameter?
I want to use lambda as template parameter, but it will not compile in c++17.我想使用 lambda 作为模板参数,但它不会在 c++17 中编译。 For example the
temp_bar<int, lambda1>
here does not work.例如,
temp_bar<int, lambda1>
此处不起作用。 It seems the non-type parameter is limited .似乎非类型参数是有限的。 Can anyone explain why this is not allowed?
谁能解释为什么这是不允许的? It will make life much easier to enable this.
实现这一点将使生活变得更加轻松。
template<typename T>
bool to_bool(T o)
{
return bool(o);
}
template <typename T, auto F=to_bool<T>>
class temp_bar
{
public:
temp_bar(T o)
: _data{o}
{
if(F(o))
std::cout << "OK\n";
}
private:
T _data;
};
int main()
{
temp_bar<int> bar1{1};
auto lambda1 = [](int o){return o==2;};
temp_bar<int, lambda1> bar2{2};
return 0;
}
This won't be possible without C++20.没有 C++20,这是不可能的。 If you want to achieve a similar result in C++17, you can do the following
如果你想在 C++17 中达到类似的结果,你可以执行以下操作
template<typename T>
bool to_bool(T o)
{
return bool(o);
}
template <typename T >
class temp_bar
{
public:
template <typename F >
temp_bar(T o, F&& fn)
: _data{o}
{
if(fn(o))
std::cout << "OK\n";
}
temp_bar(T o) : _data(o) {
if (to_bool(o))
std::cout << "OK\n";
}
private:
T _data;
};
int main()
{
temp_bar<int> bar1{1};
auto lambda1 = [](int o){return o==2;};
temp_bar<int> bar2{2,lambda1};
return 0;
}
This effectively has two constructors, one without lambda and one with a lambda.这实际上有两个构造函数,一个没有 lambda,一个有 lambda。
Ignoring the fact that the declaration of lambda1
is not constexpr
and therefore is not a constant expression and therefore could never be used as a non-type template parameter (NTTP) regardless of anything else, the main reason this is not permitted is that lambdas are not a special thing in C++.忽略这样一个事实,即
lambda1
的声明不是constexpr
,因此不是常量表达式,因此无论如何都不能用作非类型模板参数 (NTTP),不允许这样做的主要原因是 lambdas在 C++ 中不是什么特别的东西。 A lambda is just a user-defined type created by the compiler with a specialized constructor, members based on your capture list, and an operator()
overload in accord with the lambda function body and signature. lambda 只是由编译器创建的用户定义类型,具有专门的构造函数、基于捕获列表的成员以及符合 lambda 函数体和签名的
operator()
重载。 There is nothing a lambda is doing that you couldn't do without them.没有什么是 lambda 做的,没有它们你就做不到。
In C++, lambdas are just shorthand notation;在 C++ 中,lambda 只是速记符号; nothing more.
而已。
As such, if user-defined types cannot be used as NTTPs, and lambdas are user-defined types, then you cannot use lambdas as NTTPs.因此,如果用户定义的类型不能用作 NTTP,而 lambda 是用户定义的类型,则您不能将 lambda 用作 NTTP。 That's why they're disallowed.
这就是他们被禁止的原因。
And note that, while C++20 does allow some user-defined types to be used as NTTPs, the standard at present offers no guarantees as to whether any particular lambda could be used as an NTTP.请注意,虽然 C++20 确实允许将某些用户定义的类型用作 NTTP,但目前的标准不保证是否可以将任何特定的 lambda 用作 NTTP。 A user-defined type that is used as an NTTP must provide strong structural equality, and nothing in the standard requires that any lambda, even capture-less ones, provide strong structural equality.
用作 NTTP 的用户定义类型必须提供强结构相等性,并且标准中没有任何内容要求任何 lambda,即使是无捕获的 lambda,提供强结构相等性。 An implementation may do so, but such code is non-portable.
一个实现可以这样做,但这样的代码是不可移植的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.