constexpr条件不是常量



我编写了以下C++17代码:

constexpr bool gDebug = true;
template <typename T> constexpr const T& Select(const bool pCondition, const T& a, const T& b)
{
if constexpr (pCondition)
{
return a;
}
else
{
return b;
}
}

然后我这样称呼它:

int c = Select<QString>(gDebug, a, b); // In .cpp

我得到if constexpr线路的error: ‘pCondition’ is not a constant expression

为什么?这不应该奏效吗?

为什么?这不应该奏效吗?

不,不应该。pCondition不是常量表达式。我可以理解为什么这可能会令人困惑,因为pConditionconst,但术语常量表达式指的是能够在编译时对其求值。也就是说,不是const,而是真正的constexpr

函数参数不是常量表达式。您碰巧传递了一个编译时常数这一事实并不重要,因为您可以很容易地传递从stdin或其他地方读取的运行时变量。

if constexpr需要一个常量表达式,所以你真的只需要if。或者,您需要将条件提升为常量表达式,例如将其作为模板参数:

template <bool pCondition, typename T>
constexpr const T& Select(const T& a, const T& b)
{
if constexpr (pCondition) // now okay
{
return a;
}
else
{
return b;
}
}
int c = Select<qDebug>(a, b);

或者您可以要求参数是一个编码为类型的值:

template <typename Boolean, typename T>
constexpr const T& Select(Boolean pCondition, const T&, const T&);
constexpr std::true_type qDebug{}; // true_type, not bool = true
int c = Select(qDebug, a, b);      // okay

Barry是正确的,但我认为这并不是你理解错误的地方。

template <typename T> constexpr const T& Select(const bool pCondition, const T& a, const T& b)

意味着如果参数为,则函数调用在编译时是可求值的。但是,可以使用编译时未知的参数来调用该函数。在这种情况下,函数调用本身不是一个常量表达式,将在运行时进行求值。尽管从函数编程的意义上讲,它仍然是纯粹的,顺便说一句,它是noexcept

但CCD_ 11实际上意味着表达式必须在编译时可求值。

因此,由于constexpr函数可以在编译时使用未知参数进行调用,因此如果表达式依赖于这些参数,则它不能包含声明为constexpr的表达式。

所有其他答案都是正确的,并没有完全说出我想知道的内容。要使constexpr函数同时在constexpr(编译时(和变量(运行时(上下文中工作,正如Patrick所指出的,函数中不能有任何内容将其限制为constexpr上下文。更重要的是,函数在constexpr上下文中工作不需要任何此类限制。编译器解决了这个问题——它现在可以自由地(根据需要(在constexpr或运行时上下文中计算函数。因此可以简单地取出if constexpr (pCondition)中的constexpr

最新更新