C++1z 全ての非型テンプレート引数の定数式評価を許可

C++1zでは、非型テンプレート引数(non-type template argument)で扱える型はとくに変わりませんが、渡せる値についての制限緩和が行われます。

今回緩和されるのは、ポインタの値です。C++14までは、以下のような制限がありました:

  • 静的記憶域を持つ完全オブジェクトへのポインタ値もしくは参照、もしくは
  • ヌルポインタ値に評価される定数式、
  • ヌルメンバポインタ値に評価される定数式であること

つまり、staticでないオブジェクトへのポインタは、ヌルポインタしか渡せなかったのです。

C++1zではこの制限が撤廃され、定数式で評価されるポインタならなんでも渡せるようになります。その許可される定数式での評価には、配列からポインタへの変換や、関数から関数ポインタへの変換、修飾の変換なども含まれます。

struct A {};

template <const A* p>
struct X {};

constexpr A a{};
constexpr A ar[3] = {};

constexpr const A* get_pointer() { return &a; }
constexpr const A* get_array_pointer() { return ar; }

int main()
{
    X<nullptr> {};             // OK : これまで許可されていた
    X<get_pointer()> {};       // OK : C++1z
    X<get_array_pointer()> {}; // OK : C++1z
}

参照

お断り

この記事の内容は、C++1zが正式リリースされる際には変更される可能性があります。正式リリース後には、C++日本語リファレンスサイトcpprefjpの以下の階層の下に解説ページを用意する予定です。