15 尽可能的使用constexpr

15 尽可能的使用constexpr

constexprconst一样,它们是编译期可知的。但是const不提供constexpr所能保证之事,因为const对象不需要在编译期初始化它的值。

​ 简而言之,所有constexpr对象都是const,但不是所有const对象都是constexpr

constexpr函数

​ 如果实参是编译期常量,这些函数将产出编译期常量;如果实参是运行时才能知道的值,它们就将产出运行时值。

标准迭代

C++11

​ C++11中,constexpr函数的代码不超过一行语句:一个return

​ 扩展:第一,使用三元运算符“?:”来代替if-else语句,第二,使用递归代替循环。

constexpr int pow(int base, int exp) noexcept
{
return (exp == 0 ? 1 : base * pow(base, exp - 1));
}

C++14

constexpr函数限制为只能获取和返回字面值类型

constexpr int pow(int base, int exp) noexcept   //C++14
{
auto result = 1;
for (int i = 0; i < exp; ++i) result *= base;

return result;
}

constexpr对象(字面值类型)

​ 类的构造函数被声明为constexpr类型。即如果构造的入参是constexpr,产生的类对象就是constexpr

class Point {
public:
constexpr Point(double xVal = 0, double yVal = 0) noexcept
: x(xVal), y(yVal)
{}

constexpr double xValue() const noexcept { return x; }
constexpr double yValue() const noexcept { return y; }

void setX(double newX) noexcept { x = newX; }
void setY(double newY) noexcept { y = newY; }

private:
double x, y;
};

Point的构造函数可被声明为constexpr,因为如果传入的参数在编译期可知,Point的数据成员也能在编译器可知。因此这样初始化的Point就能为constexpr

constexpr Point p1(9.4, 27.7);  //没问题,constexpr构造函数
//会在编译期“运行”
constexpr Point p2(28.8, 5.3); //也没问题