Namespaces
Variants

C++ named requirements: LiteralType (since C++11)

From cppreference.net
C++ named requirements

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

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

目次

要件

リテラル型は以下のいずれかです:

  • 修飾指定(const/volatile)の可能性がある void (これにより constexpr 関数がvoidを返すことが可能);
(C++14以降)
  • スカラ型 ;
  • 参照型 ;
  • リテラル型の 配列 ;
  • 以下の全ての特性を持つ、修飾指定子(const/volatile)が付与されている可能性のあるクラス型:
  • 以下の条件を満たす trivial (C++20まで) constexpr (C++20以降) destructor を持つ、
  • すべての非静的non-variantデータメンバと基底クラスが非volatile literal typeであり、かつ
  • 以下のいずれかである
(C++17以降)
  • バリアントメンバーを持たない、または
  • 非volatileリテラル型のバリアントメンバーを少なくとも1つ持つ
  • バリアントメンバーを持たない、または
  • 非volatileリテラル型のバリアントメンバーを少なくとも1つ持つ
  • コピーコンストラクタまたはムーブコンストラクタではない constexpr (テンプレートである可能性もある)コンストラクタを少なくとも1つ持つ型

注記

型は、そのすべてのconstexprコンストラクタが削除されていても、アクセス不可能でも、オーバーロード解決に参加できなくても、リテラル型になり得ます。

struct A { constexpr A(int) = delete; char c; }; // Aはリテラル型
constexpr A v = std::bit_cast<A>('0'); // C++20で有効
                                       // vはリテラル型を持つため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で削除)
型がリテラル型かどうかをチェックする
(クラステンプレート)