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

C++ 为什么我不能使用labmda作为非类型模板参数?,c++,lambda,c++17,C++,Lambda,C++17,我想使用lambda作为模板参数,但它不会在c++17中编译。例如,此处的temp_栏不起作用。似乎非类型参数是。有人能解释为什么这是不允许的吗?这将使生活更容易实现这一点 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

我想使用lambda作为模板参数,但它不会在c++17中编译。例如,此处的
temp_栏
不起作用。似乎非类型参数是。有人能解释为什么这是不允许的吗?这将使生活更容易实现这一点

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;
}

模板
bool to_bool(to)
{
返回布尔(o);
}
模板
类临时钢筋
{
公众:
温度棒(TO)
:_数据{o}
{
如果(F(o))

这在没有C++20的情况下是不可能的。如果您想在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;
}
模板
bool to_bool(to)
{
返回布尔(o);
}
模板
类临时钢筋
{
公众:
模板
温度棒(TO、F和fn)
:_数据{o}
{
如果(fn(o))

这在没有C++20的情况下是不可能的。如果您想在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;
}
模板
bool to_bool(to)
{
返回布尔(o);
}
模板
类临时钢筋
{
公众:
模板
温度棒(TO、F和fn)
:_数据{o}
{
如果(fn(o))

std::cout忽略以下事实:
lambda1
的声明不是
constepr
,因此不是常量表达式,因此不能用作非类型模板参数(NTTP)无论如何,这是不允许的主要原因是lambda不是C++中的特殊事物。lambda只是由编译器创建的用户定义的类型,它由一个特殊的构造函数、基于捕获列表的成员和一个<代码>操作器()组成。
重载与lambda函数体和签名一致。没有lambda函数体和签名,任何lambda函数都无法完成

在C++中,lambdas只是简写符号;没有更多。

因此,如果用户定义的类型不能用作NTTP,而lambda是用户定义的类型,那么您就不能将lambda用作NTTP。这就是不允许它们的原因


请注意,虽然C++20允许某些用户定义的类型用作NTTP,但该标准目前不保证是否可以将任何特定的lambda用作NTTP。用作NTTP的用户定义类型必须提供强大的结构平等性,并且该标准中的任何内容都不要求任何lambda捕获更少的数据,提供强大的结构平等性。实现可以这样做,但这样的代码是不可移植的。

忽略以下事实:
lambda1
的声明不是
constepr
,因此不是常量表达式,因此永远不能用作非类型模板参数(NTTP)无论如何,这是不允许的主要原因是lambda不是C++中的特殊事物。lambda只是由编译器创建的用户定义的类型,它由一个特殊的构造函数、基于捕获列表的成员和一个<代码>操作器()组成。
重载与lambda函数体和签名一致。没有lambda函数体和签名,任何lambda函数都无法完成

在C++中,lambdas只是简写符号;没有更多。

因此,如果用户定义的类型不能用作NTTP,而lambda是用户定义的类型,那么您就不能将lambda用作NTTP。这就是不允许它们的原因


请注意,虽然C++20允许某些用户定义的类型用作NTTP,但该标准目前不保证是否可以将任何特定的lambda用作NTTP。用作NTTP的用户定义类型必须提供强大的结构平等性,并且该标准中的任何内容都不要求任何lambda捕获更少的数据一个,提供强大的结构平等性。一个实现可以这样做,但这样的代码是不可移植的。

模板参数必须在编译时已知。lambda直到运行时才创建。您可以在C++20:@RemyLebeau中使用capture,这只有在使用capture时才是正确的。没有capture,编译器已经知道它。@Wang:“没有捕获,编译器就已经知道了。"胡说八道。lambda是对象,不管它们是否捕获了什么。您创建的
lambda1
对象不是
constepr
对象,因此从来没有希望将其放入模板参数中。lambda是类类型的对象。在C++20之前,这些对象绝对不允许作为模板参数。如果你要问的是,这是你链接的问题的副本。模板参数必须在编译时知道。lambda直到运行时才创建。你可以在C++20:@RemyLebeau中,这只有在使用捕获时才是真的。没有捕获,编译器已经知道它。@Wang:“没有捕获,编译器已经知道它。”胡说八道。lambda是对象,不管它们是否捕获了什么。您创建的
lambda1
对象不是
constepr
对象,因此从来没有希望将其放入模板参数中。lambda是类类型的对象。在C++20之前,这些对象绝对不允许作为模板参数。如果你要问的是,这是你链接的问题的副本。