C++中constexpr的用法
简单来说声明为constexpr的函数,那么在编译阶段就能得到其返回值,故编译器可以直接将对应位置的函数调用直接转换为函数的返回值,故其实现了和内联函数一样的功能,例如:
constexpr int test() { return 10; } constxepr int i = test() * 3 + 2;编译器会直接将test()替换为10,在编译阶段就可以确定i=32。
需要注意constexpr的返回值必须是字面值类型变量(算术类型、指针、引用、字面值类等),函数形参可以是非常量,但实参必须是常量,例如:
constexpr int test(int i) { return i; } constxepr int i = test(1) * 3 + 2;是可以的,但
constexpr int test(int i) { return i; } int j =1; constxepr int i = test(j) * 3 + 2;是会报错的。
总的来说,constexpr函数用于常量表达式的函数,其遵守如下规定:
1. 返回值和形参都要是字面值;
2.不一定返回常量表达式。
最后说一下,为什么用constexpr,其优点是编译时计算出表达式的值,减少程序运行的开销。
if constexpr
C++17引入了这一用法:
template<bool Flag> void demo() { if(Flag) { int x = 0; x = x.no_member; // Flag=false 时,依然会编译报错!整个分支语法检查 } if constexpr(Flag) { int x = 0; x = x.no_member; // Flag=false:这整个分支直接丢弃,不做实例化,不会报错 } }核心特性:
- 括号内必须是编译期可求值的 bool 常量;
- 不选中的分支不会被实例化(不会编译展开);
- 只能用于函数内部,不能直接用在
using、类作用域; - 属于语句,不是类型工具,和
std::conditional形成互补
if和if constexpr对比:
- 普通
if:两个分支全部语法检查、实例化,运行时才走分支; if constexpr:条件假的分支,不实例化,不做模板展开,仅做基础语法解析。注意:未选中分支仍然要满足基础语法合法,只是不会实例化模板相关逻辑。比如不能写int {这种语法错误
end
