constexpr条件不恒定?

Sil*_*cer 0 c++ constexpr c++17 if-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;
   }
}
Run Code Online (Sandbox Code Playgroud)

然后我这样打电话:

int c = Select<QString>(gDebug, a, b); // In .cpp
Run Code Online (Sandbox Code Playgroud)

我找到error: ‘pCondition’ is not a constant expression了这if constexpr条线.

为什么?这不应该工作吗?

Bar*_*rry 5

为什么?这不应该工作吗?

不,它不应该.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);
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

  • @Silicomancer这意味着函数只能用常量表达式作为参数调用. (2认同)