C++ の名前付き要件: LiteralType (C++11 以降)
From cppreference.com
型がリテラル型であることを指定します。リテラル型は constexpr 変数の型であり、constexpr 関数から構築、操作、および返却できます。
注記: 標準では、この名前のついた要件は定義されていません。これはコア言語によって定義された型カテゴリです。一貫性のために、名前付き要件としてここに含められています。
目次 |
[編集] 要件
リテラル型は次のいずれかです。
|
(C++14以降) |
- トリビアルな(C++20まで)constexpr(C++20以降) デストラクタを持つ,
- そのすべての非静的非バリアントデータメンバーおよび基底クラスが非volatileリテラル型であること、および
- 次のいずれかであること
|
(C++17以降) |
[編集] 注釈
型は、すべての constexpr コンストラクタが削除されている、アクセス不能である、またはオーバーロード解決に参加できない場合でもリテラル型であることがあります。
struct A { constexpr A(int) = delete; char c; }; // A is a literal type constexpr A v = std::bit_cast<A>('0'); // OK in C++20 // v has literal type and thus can be constexpr
[編集] 例
文字列リテラルを拡張するリテラル型
このコードを実行
#include <cstddef> #include <iostream> #include <stdexcept> class conststr // conststr is a literal type { const char* p; std::size_t sz; public: template<std::size_t N> constexpr conststr(const char(&a)[N]) : p(a), sz(N - 1) {} constexpr char operator[](std::size_t n) const { return n < sz ? p[n] : throw std::out_of_range(""); } constexpr std::size_t size() const { return sz; } }; constexpr std::size_t count_lower(conststr s) { std::size_t c{}; for (std::size_t n{}; n != s.size(); ++n) if ('a' <= s[n] && s[n] <= 'z') ++c; return c; } // An output function that requires a compile-time constant N, for testing template<int N> struct constN { constN() { std::cout << N << '\n'; } }; int main() { std::cout << "The number of lowercase letters in \"Hello, world!\" is "; constN<count_lower("Hello, world!")>(); // the string literal is implicitly // converted to conststr }
出力
The number of lowercase letters in "Hello, world!" is 9
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| CWG 1453 | C++11 | リテラルクラスに volatile データメンバーを持たせることが可能だった | 許可されなくなった。 |
| CWG 1951 | C++11 C++14 |
cv修飾された void (C++14) およびクラス型 (C++11) がリテラル型であるか不明確だった |
現在は |
| CWG 2096 | C++11 | 共用体型がリテラルであるためには、すべての非静的データメンバーがリテラルでなければならないとされていたが、 静的データメンバーはリテラルである必要があった |
非静的データメンバーは1つだけ 必要があった |
| CWG 2598 | C++11 | 共用体型がリテラルであるためには、 少なくとも1つの非静的データメンバーを持たなければならないとされていたが、 |
非静的データメンバーを 持たなくてもよい |
[編集] 関連項目
| (C++11)(C++17で非推奨)(C++20で削除) |
型がリテラル型かどうかをチェックする (クラステンプレート) |