0%

Use constexpr whenever possible

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Point {
public:
constexpr Point(double x = 0, double y = 0) noexcept : x(x), y(y) {}

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

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

private:
double x, y;
};

constexpr Point midpoint(const Point& p1, const Point& p2) noexcept {
return {(p1.xValue() + p2.xValue()) / 2, (p1.yValue() + p2.yValue()) / 2};
}

constexpr Point reflection(const Point& p) noexcept {
Point res;
res.setX(-p.xValue());
res.setY(-p.yValue());
return res;
}

constexpr Point p1(9.4, 27.7);
constexpr Point p2(28.8, 5.3);
constexpr auto mid = midpoint(p1, p2);

constexpr auto reflectedMid = reflection(mid);

The Point constructor can be declared constexpr, because if the arguments passed to it are known during compilation, the value of the data members of the constructed Point can also be known during compilation. Points initialized could thus be constexpr. In C++14, even setters can be constexpr.

Conclusion:

  • constexpr objects are const and are initialized with values known during compilation.
  • constexpr functions can produce compile-time results when called with arguments whose values are known during compilation.
  • constexpr objects and functions may be used in a wider range of contexts than non-constexpr objects and functions.