Namespaces
Variants

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

From cppreference.net
C++ named requirements

어떤 타입이 리터럴 타입(literal type) 임을 지정합니다. 리터럴 타입은 constexpr 변수 의 타입이며, constexpr 함수 에서 생성, 조작 및 반환될 수 있습니다.

참고: 표준에서는 이 이름의 명명된 요구 사항을 정의하지 않습니다. 이는 핵심 언어에 의해 정의된 타입 범주입니다. 일관성을 위해서만 명명된 요구 사항으로 여기에 포함되었습니다.

목차

요구사항

리터럴 타입은 다음 중 하나입니다:

  • 가능하게 cv 한정된 void (그래서 constexpr 함수들이 void를 반환할 수 있음);
(C++14부터)
  • trivial (C++20 이전) constexpr (C++20 이후) destructor 를 가지고 있으며,
  • 모든 비정적(non-static) 비배리언트(non-variant) 데이터 멤버와 기본 클래스가 비휘발성(non-volatile) 리터럴 타입이며,
  • 다음 중 하나에 해당하는 경우
(since C++17)
  • variant 멤버 가 없거나,
  • volatile이 아닌 literal 타입의 variant 멤버를 최소한 하나 이상 가지고 있는 경우
  • variant 멤버 가 없거나,
  • volatile이 아닌 literal 타입의 variant 멤버를 최소한 하나 이상 가지고 있는 경우
  • 복사 생성자나 이동 생성자가 아닌 constexpr (템플릿일 수 있는) 생성자를 최소한 하나 이상 가지고 있는 타입

참고 사항

타입은 해당 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-qualified void (C++14)
및 클래스 타입(C++11)이 리터럴 타입인지 불명확했음
리터럴 타입임
CWG 2096 C++11 union 타입이 리터럴이 되려면 모든 비정적
데이터 멤버가 리터럴이어야 했음
하나의 비정적 데이터
멤버만 필요함
CWG 2598 C++11 union 타입이 리터럴이 되려면 적어도
하나의 비정적 데이터 멤버가 있어야 했음
비정적 데이터 멤버가
없어도 될 수 있음

참고 항목

(C++11) (deprecated in C++17) (removed in C++20)
타입이 리터럴 타입인지 검사합니다
(클래스 템플릿)