I wrote the following C++17 code:
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;
}
}
Then I called it like this:
int c = Select<QString>(gDebug, a, b); // In .cpp
I get error: ‘pCondition’ is not a constant expression
for the if constexpr
line.
Why? Shouldn't this work?
Why? Shouldn't this work?
No, it shouldn't. pCondition
is not a constant expression. I can see why this might be confusing, since pCondition
is const
- but the term constant expression refers to it being able to be evaluated at compile time. That is, not const
but really constexpr
.
Function parameters are not constant expressions. The fact that you happen to pass a compile-time constant is immaterial, since you could just as easily pass a runtime variable that you read from stdin or something.
if constexpr
requires a constant expression, so you really just want if
there. Or, you need to lift the condition to be a constant expression - such as by making it a template parameter:
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);
or you could require that the parameter be a value encoded into a type:
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