C++17 if constexpr编译期条件分支详解
请说明C++17 if constexpr的语法、编译期条件分支机制,以及在模板元编程中的典型应用(简化SFINAE、替代enable_if),并比较其与普通if在模板中的行为差异。
回答
我是大山
if constexpr:在编译期对条件求值,为true的分支被编译,false分支的代码被丢弃(不被实例化)。
template<typename T>
auto getValue(T t) {
if constexpr (std::is_pointer_v<T>) return *t;
else if constexpr (std::is_integral_v<T>) return t;
else return t; // 兜底
}
关键特性:
- 废弃分支不实例化:被丢弃分支中的模板代码即使语法上对当前类型无效也不会产生编译错误。
- 必须有明确的返回类型(所有分支返回类型需一致)。
- 可用于任意bool常量表达式,不限于类型萃取。
与普通if的区别:
- 普通if在模板中,两个分支都会实例化,可能导致编译错误:
// 若T不是指针,*t仍是语法错误
if (std::is_pointer_v<T>) return *t; else return t;
- if constexpr不会产生此类问题。
替代SFINAE/enable_if:
// C++11 SFINAE
// C++17 if constexpr 更简洁
if constexpr (has_size_v<T>) { /* */ }
注意:if constexpr不能替代概念约束(concept约束有更强语义和错误信息)。