やさしいconstexpr(1) - NF
つづきです
関数にconstexprを指定する
変数にconstexprを指定するように、関数にもconstexprを指定できる。
前回、実行時定数にconstexprを指定してコンパイル時定数にしたので、今回はコンパイル時定数を返す関数を考える。
#include <iostream> class MyArray{ public: MyArray() = delete; // デフォルトコンストラクタは使わない MyArray(const size_t size) : N(size) {} size_t size() const { return N; } const size_t N; }; int main() { const MyArray x(10); int arr[x.size()] = {1}; }
MyArrayのサイズはコンパイル時に分かるはずだが、MyArray.size()はコンパイル時定数ではないので、前回の最初の例と同じく「int a[arr.size()] 」の宣言はコンパイルエラーになる。
これも、MyArray型変数の宣言をconstからconstexprに変えて、MyArray.size()にconstexprを指定する事でコンパイルが・・・通りませんでした。なんで?
#include <iostream> class MyArray{ public: MyArray() = delete; // デフォルトコンストラクタは使わない MyArray(const size_t size) : N(size) {} constexpr size_t size() const { return N; } const size_t N; }; int main() { constexpr MyArray x(10); int arr[x.size()] = {1}; }
main.cpp: In function 'int main()': main.cpp:11:27: error: call to non-'constexpr' function 'MyArray::MyArray(size_t)' 11 | constexpr MyArray x(10); | ^ main.cpp:5:5: note: 'MyArray::MyArray(size_t)' declared here 5 | MyArray(const size_t size) : N(size) {} | ^~~~~~~ main.cpp:12:9: warning: ISO C++ forbids variable length array 'arr' [-Wvla] 12 | int arr[x.size()] = {1}; | ^~~
MyArray型変数をconstexpr指定で生成してるのに、MyArrayのコンストラクタがconstexpr指定されてないよ、とのこと(合ってる?)。確かに。と言う訳で、MyArrayのコンストラクタにconstexprを指定すると無事にコンパイルが通りました。
以上のように、関数にconstexprを指定することで定数を使える幅が広がりました。