简体   繁体   English

为什么我不能使用 labmda 作为非类型模板参数?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM