C++学习——if constexpr
可以把if constexpr理解为编译时if,只有被选中的if constexpr分支才会被实例化。
template<typename T>
void update(T& target){
//...
if constexpr(is_pod<T>::value){
simple_and_fast(target);//用于"普通旧数据"
}else{
slow_and_safe(target);
}
//...
}
这里is_pod<T>是一个类型萃取函数,用来说明一个类型是否可以简单拷贝。在C++20引入概念和约束之后,我们就可以使用概念来代替类型萃取函数和低级技术(例如基于enable_if的重载)
if constexpr不是一种文本处理机制,因此不能用来打破常规的语法、类型和作用域规则。
template<typename T>
auto minus(T a,T b)
-> std::conditional_t<std::is_same_v<T, double>, double, int> {
if constexpr (std::is_same<T,double>::value){
if(std::abs(a-b)<0.0001){
return 0.;
}else{
return a - b;
}
} else{
return static_cast<int>(a - b);
}
}
当实参为整型时一切正常,但当实参类型为double时,除了代码块内部返回结果类型为double,代码块外部的return static_cast<int>(a - b); 依然会正常编译导致出现两个不同的返回类型而报错。
特别注意:if constexpr不支持短路规则。简单举例
template<typename T>
auto any2i(T t)
-> std::conditional_t<std::is_same_v<T, std::string>, int, T> {
if constexpr (std::is_same<T, std::string>::value&&T::npos == -1) {
return atoi(t.c_str());
}else {
return t;
}
}
下面这种写法是错的,因为当 T 不是 std::string 时,T::npos == -1 仍可能被编译,从而导致失败:
if constexpr (std::is_same_v<T, std::string> && T::npos == -1) {
return std::atoi(t.c_str());
} else {
return t;
}
正确写法应把条件拆成嵌套的 if constexpr:
// 正确写法
if constexpr (std::is_same_v<T, std::string>) {
if constexpr (T::npos == -1) {
return std::atoi(t.c_str());
}
} else {
return t;
}

浙公网安备 33010602011771号