在c++17之前,我们没有if constexpr,所以选择的是if,这意味着不能保证我们的constexpr函数在编译时得到评估,一切都取决于编译器的实现
if 语句不是 constexpr 这一事实并不意味着它不能在编译时作为 constexpr 表达式的一部分进行计算。在你的例子中,v
在这两种情况下都会在编译时求值,因为它必须是:它是一个常量表达式。这不是实现定义的。
在 c++17 之后,如果我们希望 constexpr 函数在编译时求值,则首选 constexpr。
Constexpr if 语句的引入是为了解决问题。让 constexpr 函数在编译时求值并不是这个问题。
这是一个示例,其中constexpr if
是必需的而不是简单的if
(取自参考参数 https://en.cppreference.com/w/cpp/language/if):
template <typename T>
auto get_value(T t) {
if constexpr(std::is_pointer_v<T>)
return *t; // deduces return type to int for T = int*
else
return t; // deduces return type to int for T = int
}
尝试删除constexpr
关键字并看看会发生什么(demo http://coliru.stacked-crooked.com/a/db1f05c4410783f8).
另请注意,您始终可以使用其他方法解决该问题,但是if constexpr
具有简洁的优点。例如,这是一个等价的get_value
使用标签调度:
template<typename T>
auto get_value_impl(T t, std::true_type) {
return *t;
}
template<typename T>
auto get_value_impl(T t, std::false_type) {
return t;
}
template<typename T>
auto get_value(T t) {
return get_value_impl(t, std::is_pointer<T>{});
}
Demo http://coliru.stacked-crooked.com/a/fe2e23a57d6c8312