在C++11中,constexpr 函数有着严格的限制:函数体通常只能包含一条return语句(有时可以使用一些简单的表达式,但不能有循环、局部变量等)。
1 // error: body of 'constexpr' function 'constexpr int func(int)' not a return-statement
2 // warning: Use of this statement in a constexpr function is a C++14 extension
3 constexpr int func(int nIndex)
4 {
5 if(nIndex == 0)
6 return 0;
7 else if(nIndex < 10)
8 return nIndex;
9 else
10 return nIndex * 10;
11 }
C++14放宽了这些限制,允许在constexpr函数中使用更多的C++语法,比如局部变量、循环、条件语句等(但仍然不能有某些东西,如goto、try块、非字面类型的变量等)。
C++14中 constexpr 函数的主要放宽点:
- 允许局部变量:在C++11中,constexpr函数体内不能有局部变量,而C++14允许定义局部变量,只要这些变量是字面类型并且被初始化。
- 允许循环:C++14允许在constexpr函数中使用循环(for、while、do-while)。
- 允许条件语句:C++11中条件语句(if-else)只能使用条件运算符(?:)来模拟,而C++14允许使用if和switch。
- 允许修改局部变量:在C++14中,constexpr函数内可以修改局部变量,只要这些变量的生命周期在constexpr函数内。
- 允许多个return语句:C++11中只能有一个return语句,C++14中可以有多个,只要在编译时能够确定返回常量表达式。
- 允许 void 返回类型,C++11中,constexpr 函数的返回值类型不能是void。
仍然禁止的行为:
- constexpr 函数内部不能有 static 变量。
1 constexpr int with_static()
2 {
3 // warning: Definition of a static variable in a constexpr function is a C++23 extension
4 static int counter = 0; // 不允许
5 return ++counter;
6 }
- constexpr 函数内部不能有try-catch 语句。
constexpr int with_exception()
{
// warning: Use of this statement in a constexpr function is a C++20 extension
try
{ // 不允许
return 1;
} catch (...)
{
return 0;
}
}
- constexpr 函数内部不能调用非 constexpr 函数。
1 int runtime_function()
2 {
3 return 42;
4 }
5
6 constexpr int call_runtime()
7 {
8 // error: call to non-'constexpr' function 'int runtime_function()'
9 return runtime_function(); // 不允许
10 }