C++Builderでconstexprを使用する
概要
このサポート情報では、constexpr変数とconstexpr関数を利用する方法を学習します。このライブラリを利用する理由は、実行時ではなくコンパイル時に計算を実行するアプリケーションのパフォーマンスの向上させることで、コンパイル時に時間を割り当てることにより、結果的に実行時間を節約することが目的です。
constexprキーワードはC++11で導入され、C++14およびC++17で改善されました。
constexprは、オブジェクトまたは関数の値をコンパイル時に評価でき、その式を他の定数式で使用できることを指定します。 任意のコードが値を変更しようとすると、コンパイラエラーが発生します。constとは異なり、constexprは関数やクラスコンストラクタにも適用できます。 constexpr は、値または戻り値が定数であり、可能な場合はコンパイル時に計算されます。
const変数とconstexpr変数の主な違いは、const変数の初期化を実行時まで延期できることです。 constexpr変数は、コンパイル時に初期化する必要があります。 さらにconstexpr変数または関数のすべての宣言には、constexpr指定子が必要です。
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では、コンパイル時に条件式を推定することができます。これにより、コンパイラは誤った分岐を排除できます。
template<typename T>
auto get_value(T t) {
if constexpr (std::is_pointer_v<T>) {
return *t;
} else {
return t;
}
}
constexprを使えば、もっと驚くようなことができるようになります。ぜひ、以下のワークショップを参考してください。
constexpr関数は、関数にconstexprを指定することで、コンパイル時に関数を実行できるようになります。また実行時の値が実引数として渡された場合は、実行時に評価されます。なお、constexpr関数またはコンストラクタは暗黙のうちにインラインになります。
constexpr int method_call(int a, int b) {
return a * b;
}
それでは、constexpr変数、constexpr関数を利用したユースケースを見てみましょう。
#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;
}
このブログで紹介しましたサンプルコードは、こちらからダウンロードできます。
関連情報