自分(が知らない人に説明する)用
長いうえに情報量少ないです
constexprってなに
- C++11で導入された汎用的に定数式を表現するための機能
- 読み方は「こんすとえくすぷれっしょん」らしい
なにがうれしいの
色々あるみたいだけど、一番単純そうな例を。
構造体になにかのサイズが入っていて、そのサイズ分の配列を宣言したい状況を考える。
struct X { int size; }; int main() { const X x = {10}; int arr[x.size] = {1}; }
これは、実装した人の期待に反してコンパイルエラーになる。(gcc13.0で-pedantic -Werrorを指定してます)
$ g++ -std=c++11 -O0 -pedantic main.cpp main.cpp: In function 'int main()': main.cpp:4:9: warning: ISO C++ forbids variable length array 'arr' [-Wvla] 4 | int arr[x.size] = {1};
しかし、constではなくconstexprを使うとエラーにならない。うれしいね。
struct X { int size; }; int main() { constexpr X x = {10}; int arr[x.size] = {1}; }
おわり
補足:なんでconstとconstexprで違いが出るの
C++には「コンパイル定数」と「実行時定数」の2種類があって、intのような整数型以外のconst変数は「実行時定数」になる。(※)
対して、固定長配列のサイズは「コンパイル定数」しか指定できないと決まっている。
なので、最初の例はコンパイルエラーになるが、次の例はコンパイルが通る。
※整数型以外は「コンパイル定数」にならないので、例えば
const int size = 10; int arr[size] = {1};
はコンパイルが通るけど
const float size = 10; int arr[(int)size] = {1};
はコンパイルエラーになる。(こんな事しないだろうけど)
これも同じく、size変数をconstexprにするとコンパイルが通る。