C++11でmax/min/powをコンパイル時計算
C++11のconstexprを使うと、従来は実行時のみに限定されていた定数計算をコンパイル時に行うことができる。これによって、例えば配列の引数にmin/max/階乗等の計算を用いることができる。
pow()の例は、Effective Modern C++のItem 15で解説されている。
Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14
- 作者: Scott Meyers
- 出版社/メーカー: O'Reilly Media
- 発売日: 2014/11/10
- メディア: Kindle版
- この商品を含むブログ (1件) を見る
min/maxについては、Lisp風に可変長引数を取れるようにしてある。
#include<iostream> template<class T> constexpr T smax(T a) noexcept { return a; } template<class T> constexpr T smax(T a, T b) noexcept { return a > b ? a : b; } template<class T, class ... Args> constexpr T smax(T a, T b, Args ... args) noexcept { return smax(a, smax(b, args...)); } template<class T> constexpr T smin(T a) noexcept { return a; } template<class T> constexpr T smin(T a, T b) noexcept { return a > b ? b : a; } template<class T, class ... Args> constexpr T smin(T a, T b, Args ... args) noexcept { return smin(a, smin(b, args...)); } template<class T> constexpr T spow(T base, T exp) noexcept { //static_assert(exp >= 0, "Exponent must not be negative"); return exp <= 0 ? 1 : exp == 1 ? base : base * spow(base, exp-1); } int main() { int foo[ smax(spow(2,5), smax(5,2,3)) ]; std::cout << "int foo[" << (sizeof(foo) / sizeof(foo[0])) << "]" << std::endl; return 0; }
実行結果:
$ clang++ -std=c++11 static_minmax.cpp && ./a.out int foo[16]