このブログでは、constexpr変数とconstexpr関数を利用する方法を学習します。このライブラリを利用する理由は、実行時ではなくコンパイル時に計算を実行するアプリケーションのパフォーマンスの向上させることで、コンパイル時に時間を割り当てることにより、結果的に実行時間を節約することが目的です。
constexprキーワードはC++11で導入され、C++14およびC++17で改善されました。
constexprは、オブジェクトまたは関数の値をコンパイル時に評価でき、その式を他の定数式で使用できることを指定します。 任意のコードが値を変更しようとすると、コンパイラエラーが発生します。constとは異なり、constexprは関数やクラスコンストラクタにも適用できます。 constexpr は、値または戻り値が定数であり、可能な場合はコンパイル時に計算されます。
const変数とconstexpr変数の主な違いは、const変数の初期化を実行時まで延期できることです。 constexpr変数は、コンパイル時に初期化する必要があります。 さらにconstexpr変数または関数のすべての宣言には、constexpr指定子が必要です。
1 2 3 4 5 6 |
constexpr float x = 42.0; constexpr float y{108}; constexpr float z = exp(5, 3); constexpr int i; // Error! Not initialized int j = 0; constexpr int k = j + 1; //Error! j not a constant expression |
C++17では、コンパイル時に条件式を推定することができます。これにより、コンパイラは誤った分岐を排除できます。
1 2 3 4 5 6 7 8 |
template<typename T> auto get_value(T t) { if constexpr (std::is_pointer_v<T>) { return *t; } else { return t; } } |
constexprを使えば、もっと驚くようなことができるようになります。ぜひ、以下のワークショップを参考してください。
constexpr関数は、関数にconstexprを指定することで、コンパイル時に関数を実行できるようになります。また実行時の値が実引数として渡された場合は、実行時に評価されます。なお、constexpr関数またはコンストラクタは暗黙のうちにインラインになります。
1 2 3 |
constexpr int method_call(int a, int b) { return a * b; } |
それでは、constexpr変数、constexpr関数を利用したユースケースを見てみましょう。
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
#ifdef _WIN32 #include <tchar.h> #else typedef char _TCHAR; #define _tmain main #endif #include <cmath> #include <iostream> #include <memory> constexpr int method_call(int a, int b) { return a * b; } constexpr auto degrees_to_radians(const double degrees) { return degrees * (M_PI / 180.0); } constexpr int sum(int n) { if (n > 0) { return n + sum(n - 1); } return n; } template<typename T> auto get_value(T t) { if constexpr (std::is_pointer_v<T>) { return *t; } else { return t; } } int _tmain(int argc, _TCHAR* argv[]) { constexpr int i = 1 + 2; constexpr int j = method_call(5, 10); constexpr auto radians = degrees_to_radians(90); constexpr auto sum_one_to_ten = sum(10); int a = 5; int* pa = &a; int at = 5; int* pt = &at; auto value_a = get_value(a); auto value_pa = get_value(pa); std::cout << value_a << std::endl; std::cout << value_pa << std::endl; system("pause"); return 0; } |
このブログで紹介しましたサンプルコードは、こちらからダウンロードできます。
C++Builder 10.4では、最新のC++17の言語仕様をサポートしており、C++17の新機能もすぐに試せます。製品の詳細は、こちらを参照してください。
「C++Builderで使用方法を学ぶ」シリーズのバックナンバー
- C++BuilderでC++17ラムダ式の使用方法を学ぶ
- C++Builderで高いパフォーマンスを実現するC++17 string_viewの使用方法を学ぶ
- C++Builderで戻り値の型推論(auto)の使用方法を学ぶ
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition