当在constexpr函数中使用模板非类型类或普通参数时

问题描述 投票:2回答:1

我不清楚何时在constexpr函数中使用非类型模板参数(C ++ 20)或普通参数。对我来说,尚不清楚限制是什么,何时从纯参数切换到non-type template parameters(请参阅Live)。这是一个使用普通参数

的笨拙示例。
template<typename Tuple, typename Pred>
constexpr auto getLambda(Tuple&& tuple, Pred&& pred)
{
   return [=](auto I, auto J) {
        return pred(std::get<I>(tuple), std::get<J>(tuple));
   };
}

template<typename T>
struct A
{
    constexpr A(T t) : val(t){};
    T val;
};

int main()
{
    static constexpr auto t = std::make_tuple(A{10.0}, A{1});
    constexpr auto p   = [](auto&& a, auto&& b) { return a.val < b.val; };
    constexpr auto s   = getLambda(t, p);
    //constexpr auto b = s(1,0); // that does unfortunately not compile -> go back write differently... :-|||
}

[通常,我首先尝试使用如上所述的普通参数,并在麻烦解决non-constant表达式的编译错误之后,尝试使用template<auto t>(非类型模板参数。通常每个方法都有两个实现,情况(对我来说这似乎很愚蠢...)

在我看来,使用C ++ 20的现代泛型编程倾向于使用constexpr和一些类型元编程来进行编译时计算。任何人都可以对这种相当新的C ++“黑暗角落”有所了解。我可能误会了什么时候不是constant-expression,什么时候...

c++ constexpr c++20 constant-expression
1个回答
1
投票

简短版本:使用非类型模板参数设置非类型模板参数(在任何地方都需要constant expression时更通用)以及其他所有参数的常规参数。

关于constexpr函数的所有注意事项是,它们也可以在运行时调用。因此,每个常规参数都不一定是常量表达式。因此,您不能使用它来提供非类型的模板参数(如I中的std::get<I>)。

当然,可以辩称,当调用它来计算constexpr变量时,传递的参数始终是常量表达式,因此也可以在函数内部使用。但是,如果constexpr函数在编译时起作用但在运行时不再起作用,这将是意外的。

人们可以期望,在C ++ 20中使用新的consteval关键字,就可以在常量表达式中对consteval函数使用常规参数,因为我们知道这些参数必须是常量表达式。但这似乎并非如此:consteval为什么我不知道这种情况。但总的来说,我喜欢普通变量和非类型模板参数之间的分隔。

© www.soinside.com 2019 - 2024. All rights reserved.