namespace std {
template <class T>
struct is_literal_type;
template <class T>
inline constexpr bool is_literal_type_v = is_literal_type<T>::value; // C++17
}
この機能は、C++17から非推奨となり、C++20で削除された。
概要
型Tがリテラル型か調べる。
要件
型remove_all_extents<T>::typeは、完全型か、const/volatile修飾された(あるいはされていない)voidでなければならない。
効果
is_literal_typeは、型Tがリテラル型であるならばtrue_typeから派生し、そうでなければfalse_typeから派生する。
リテラル型とは、以下のいずれかの条件を満たす型である:
- スカラ型
- リテラル型への参照
- リテラル型の配列
- 以下の全ての特性を持つクラス型
- トリビアルなデストラクタを持つ
- 全てのコンストラクタが、定数式で初期化できること
- 集成体であること、もしくはコピー/ムーブコンストラクタ以外の
constexprコンストラクタやconstexprコンストラクタテンプレートを一つ以上持っていること - 全てのメンバ変数および基底クラスがリテラル型であること
void(C++14から)
リテラル型は、constexpr関数のパラメータおよび戻り値の型に対する制約として使用されている。
非推奨・削除の詳細
この型特性は、ジェネリックコードにおいて特定の型がconstexprに振る舞えるかを判定する機能を持つが、ユーザー定義型の場合には「少なくとも一つ以上のconstexprコンストラクタを持つこと」という条件になっていた。しかし、いずれかのコンストラクタがconstexprで、それ以外がconstexprコンストラクタではなく、それに意味がある場合に、この型特性は使いにくかった。
実際に必要となるのは、特定の型がconstexprに振る舞えるかではなく、特定の構築処理で定数初期化ができるかであるため、リテラル型という考え方は廃止すべきである、という結論になった。
例
#include <type_traits>
struct X {
int value;
constexpr X(int value)
: value(value) {}
};
static_assert(std::is_literal_type<int>::value, "int is literal type");
static_assert(std::is_literal_type<void>::value, "void is literal type");
static_assert(std::is_literal_type<X>::value, "X is literal type");
int main() {}
出力
バージョン
言語
- C++11
処理系
- Clang: 3.1 ✅
- GCC: 4.6.4 ✅
- Visual C++: 2012 ✅, 2013 ✅, 2015 ✅
- 2012~2013は、C++11の定義に基づく実装となっている。すなわち、テンプレート実引数として
voidを渡すとstd::false_typeからの派生になる。
- 2012~2013は、C++11の定義に基づく実装となっている。すなわち、テンプレート実引数として
備考
Clang 3.0では、上記サンプルにおけるX型が、リテラル型と見なされない。この問題は、Clang 3.1で修正されている。
参照
- LWG Issue 2015. Incorrect pre-conditions for some type traits
- C++11では要件が「型
Tは完全型であるか、const/volatile修飾された(あるいはされていない)voidか、要素数不明の配列型でなければならない。」だったが、これは間違いであるため、C++14で「型remove_all_extents<T>::typeは、完全型か、const/volatile修飾された(あるいはされていない)voidでなければならない。」に変更された。
- C++11では要件が「型
- P0006R0 Adopt Type Traits Variable Templates from Library Fundamentals TS for C++17
- P0174R2 Deprecating Vestigial Library Parts in C++17
- P0619R4 Reviewing deprecated facilities of C++17 for C++20
- LWG Issue
is_literal_type_vshould beinline