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の以下の階層の下に解説ページを用意する予定です。