名前空間
変種
操作

C++ の名前付き要件: LiteralType (C++11 以降)

From cppreference.com
 
 
C++ 名前付き要件
 

型がリテラル型であることを指定します。リテラル型は constexpr 変数の型であり、constexpr 関数から構築、操作、および返却できます。

注記: 標準では、この名前のついた要件は定義されていません。これはコア言語によって定義された型カテゴリです。一貫性のために、名前付き要件としてここに含められています。

目次

[編集] 要件

リテラル型は次のいずれかです。

  • cv修飾される可能性のある void (これにより constexpr 関数が void を返せるようになります);
(C++14以降)
  • スカラー型;
  • 参照型;
  • リテラル型の配列;
  • cv修飾される可能性のあるクラス型で、次のすべてのプロパティを持つもの
  • トリビアルな(C++20まで)constexpr(C++20以降) デストラクタを持つ,
  • そのすべての非静的非バリアントデータメンバーおよび基底クラスが非volatileリテラル型であること、および
  • 次のいずれかであること
(C++17以降)
  • a バリアントメンバーがない, または
  • 非volatileリテラル型の少なくとも1つのバリアントメンバーを持つ,
  • a バリアントメンバーがない, または
  • 非volatileリテラル型の少なくとも1つのバリアントメンバーを持つ,
  • コピーコンストラクタまたはムーブコンストラクタではない、少なくとも1つの constexpr (テンプレートである可能性もある) コンストラクタを持つ型。

[編集] 注釈

型は、すべての 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で削除)
型がリテラル型かどうかをチェックする
(クラステンプレート) [編集]
English 日本語 中文(简体) 中文(繁體)