Namespaces
Variants

User-defined literals (since C++11)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

ユーザー定義の接尾辞を定義することで、整数、浮動小数点、文字、および文字列リテラルがユーザー定義型のオブジェクトを生成できるようにします。

目次

翻訳の説明: - 「Contents」を「目次」に翻訳しました - C++関連の専門用語(Syntax、Literal operators、Keywords、Examples、Standard library、Defect reports)は原文のまま保持しました - HTMLタグ、属性、クラス名、IDなどは一切変更していません - 数値やリンクなどの書式も完全に保持しています

構文

ユーザー定義リテラルは、以下のいずれかの形式の式です

decimal-literal ud-suffix (1)
octal-literal ud-suffix (2)
hex-literal ud-suffix (3)
binary-literal ud-suffix (4)
fractional-constant exponent-part  (optional) ud-suffix (5)
digit-sequence exponent-part ud-suffix (6)
character-literal ud-suffix (7)
string-literal ud-suffix (8)
**注記:** - すべてのC++専門用語(decimal-literal、ud-suffixなど)は原文のまま保持されています - HTMLタグと属性は完全に保持されています - 数値の(1)〜(8)は変更されていません - (optional)はC++仕様の一部として保持されています - フォーマットと構造は完全に維持されています
1-4) ユーザー定義整数リテラル、例えば 12 _km
5-6) ユーザー定義浮動小数点リテラル、例えば 0.5 _Pa
7) ユーザー定義文字リテラル、例えば 'c' _X
8) ユーザー定義文字列リテラル、例えば "abd" _L または u "xyz" _M
decimal-literal - 整数リテラル と同じ、非ゼロの10進数字の後に0個以上の10進数字が続くもの
octal-literal - 整数リテラル と同じ、ゼロの後に0個以上の8進数字が続くもの
hex-literal - 整数リテラル と同じ、 0x または 0X の後に1個以上の16進数字が続くもの
binary-literal - 整数リテラル と同じ、 0b または 0B の後に1個以上の2進数字が続くもの
digit-sequence - 浮動小数点リテラル と同じ、10進数字の並び
fractional-constant - 浮動小数点リテラル と同じ、 digit-sequence の後にドット( 123 . )が続くもの、またはオプションの digit-sequence の後にドットと別の digit-sequence が続くもの( 1.0 または .12
exponent-part - 浮動小数点リテラル と同じ、文字 e または文字 E の後にオプションの符号と digit-sequence が続くもの
character-literal - 文字リテラル と同じ
string-literal - 文字列リテラル と同じ、raw文字列リテラルを含む
ud-suffix - 識別子、 リテラル演算子 または リテラル演算子テンプレート 宣言によって導入される( 下記 を参照)

整数リテラル および 浮動小数点リテラル の数字シーケンスにおいて、任意の2つの数字の間に区切り文字 ' をオプションで使用できます。

(C++14以降)

トークンがユーザー定義リテラル構文と通常のリテラル構文の両方に一致する場合、それは通常のリテラルであると見なされます(つまり、 LL 123LL でオーバーロードすることは不可能です)。

コンパイラがユーザー定義リテラルに ud-suffix X が付いたものを検出すると、 非修飾名前探索 を実行し、 operator "" X という名前の関数を探します。探索が宣言を見つけられない場合、プログラムは不適格となります。それ以外の場合、

1) ユーザー定義整数リテラルについて、
a) オーバーロード集合がパラメータ型 unsigned long long を持つリテラル演算子を含む場合、ユーザー定義リテラル式は関数呼び出し operator "" X ( n  ULL ) として扱われます。ここで n ud-suffix なしのリテラルです。
b) それ以外の場合、オーバーロードセットは生リテラル演算子または数値リテラル演算子テンプレートのいずれか一方(両方ではない)を含まなければならない。オーバーロードセットが生リテラル演算子を含む場合、ユーザー定義リテラル式は関数呼び出し operator "" X ( " n  ") として扱われる;
c) それ以外の場合、オーバーロードセットが数値リテラル演算子テンプレートを含む場合、ユーザー定義リテラル式は関数呼び出し operator "" X < ' c1  ' , ' c2  ' , ' c3  ' ..., ' ck  ' > ( ) として扱われます。ここで c1 から ck n の個々の文字であり、それらすべてが 基本文字セット に含まれます。
2) ユーザー定義浮動小数点リテラルについて、
a) オーバーロードセットにパラメータ型 long double を持つリテラル演算子が含まれている場合、ユーザー定義リテラル式は関数呼び出し operator "" X ( f   L ) として扱われます。ここで f ud-suffix なしのリテラルです。
b) それ以外の場合、オーバーロードセットは生リテラル演算子または数値リテラル演算子テンプレートのいずれか一方(両方ではない)を含まなければならない。オーバーロードセットが生リテラル演算子を含む場合、ユーザー定義リテラル式は関数呼び出し operator "" X ( " f   ") として扱われる;
c) それ以外の場合、オーバーロードセットが数値リテラル演算子テンプレートを含む場合、ユーザー定義リテラル式は関数呼び出し operator "" X < ' c1  ' , ' c2  ' , ' c3  ' ..., ' ck  ' > ( ) として扱われます。ここで c1 から ck f の個々の文字であり、それらすべてが 基本文字セット に含まれます。
3) ユーザー定義文字列リテラルにおいて、 str ud-suffix なしのリテラルとします:
a) オーバーロード集合が、文字列リテラル演算子テンプレートを含み、そのテンプレートパラメータが定数であり、 str が適切なテンプレート引数である場合、ユーザー定義リテラル式は関数呼び出し operator "" X < str > ( ) として扱われる;
(C++20以降)
b) それ以外の場合、ユーザー定義リテラル式は関数呼び出し operator "" X ( str, len ) として扱われます。ここで len は、終端のnull文字を除く文字列リテラルの長さです。
4) ユーザー定義文字リテラルでは、ユーザー定義リテラル式は関数呼び出し operator "" X ( ch ) として扱われます。ここで ch ud-suffix なしのリテラルです。
long double operator ""_w(long double);
std::string operator ""_w(const char16_t*, size_t);
unsigned    operator ""_w(const char*);
int main()
{
    1.2_w;    // operator ""_w(1.2L) を呼び出す
    u"one"_w; // operator ""_w(u"one", 3) を呼び出す
    12_w;     // operator ""_w("12") を呼び出す
    "two"_w;  // エラー: 適用可能なリテラル演算子が存在しない
}

文字列リテラルの連結が 翻訳フェーズ6 で行われる際、ユーザー定義文字列リテラルも連結され、その ud-suffix は連結の目的では無視されます。ただし、連結されたすべてのリテラルに現れるサフィックスは1つのみである必要があります:

int main()
{
    L"A" "B" "C"_x;  // OK: L"ABC"_x と同じ
    "P"_x "Q" "R"_y; // エラー: 2つの異なるユーザー定義サフィックス (_x と _y)
}

リテラル演算子

ユーザー定義リテラルによって呼び出される関数は、 literal operator (または、テンプレートである場合は literal operator template )として知られています。これは他の function function template と同様に名前空間スコープで宣言されます(friend関数、関数テンプレートの明示的なインスタンス化または特殊化、using宣言によって導入されることもあります)。ただし、以下の制限が適用されます:

この関数の名前は、次の2つの形式のいずれかを取ることができます:

operator "" identifier (1) (非推奨)
operator user-defined-string-literal (2)
identifier - この関数を呼び出すユーザー定義リテラルの ud-suffix として使用する identifier
user-defined-string-literal - 文字シーケンス "" に続けて(スペースなしで)記述され、 ud-suffix となる文字シーケンス
1) リテラル演算子を宣言します。
2) リテラル演算子を宣言します。この構文により、言語キーワードや 予約識別子 ud-suffix として使用することが可能になります。例えば、 operator "" if はヘッダ <complex> で定義されています。

ud-suffix はアンダースコア _ で始まらなければなりません:アンダースコアで始まらないサフィックスは、標準ライブラリが提供するリテラル演算子のために予約されています。また、ダブルアンダースコア __ を含むこともできません:そのようなサフィックスも同様に予約されています。

リテラル演算子がテンプレートである場合、空のパラメータリストを持たなければならず、また単一のテンプレートパラメータのみを持つことができます。そのテンプレートパラメータは、要素型が char である定数テンプレートパラメータパックでなければなりません(この場合、これは 数値リテラル演算子テンプレート として知られています):

template<char...>
double operator ""_x();

またはクラス型の定数テンプレートパラメータ(この場合、 string literal operator template として知られる):

struct A { constexpr A(const char*); };
template<A a>
A operator ""_a();
(C++20以降)

リテラル演算子で許可されているパラメータリストは以下のみです:

( const char * ) (1)
( unsigned long long int ) (2)
( long double ) (3)
( char ) (4)
( wchar_t ) (5)
( char8_t ) (6) (C++20以降)
( char16_t ) (7)
( char32_t ) (8)
( const char * , std::size_t ) (9)
( const wchar_t * , std::size_t ) (10)
( const char8_t * , std::size_t ) (11) (C++20以降)
( const char16_t * , std::size_t ) (12)
( const char32_t * , std::size_t ) (13)
1) このパラメータリストを持つリテラル演算子は 生リテラル演算子 であり、整数および浮動小数点ユーザー定義リテラルのフォールバックとして使用されます(上記参照)
2) これらのパラメータリストを持つリテラル演算子は、ユーザー定義整数リテラルの第一選択リテラル演算子です
3) これらのパラメータリストを持つリテラル演算子は、ユーザー定義浮動小数点リテラルの第一選択リテラル演算子です
4-8) これらのパラメータリストを持つリテラル演算子は、ユーザー定義文字リテラルによって呼び出されます
9-13) これらのパラメータリストを持つリテラル演算子は、ユーザー定義文字列リテラルによって呼び出されます

デフォルト引数 は許可されていません。

C language linkage は許可されていません。

上記の制限を除いて、リテラル演算子とリテラル演算子テンプレートは通常の関数(および関数テンプレート)であり、インラインまたはconstexprとして宣言でき、内部リンケージまたは外部リンケージを持ち、明示的に呼び出し可能で、そのアドレスを取得できるなど。

#include <string>
void        operator ""_km(long double); // OK, 1.0_km で呼び出される
void        operator "" _km(long double); // 上記と同じ、非推奨
std::string operator ""_i18n(const char*, std::size_t); // OK
template<char...>
double operator ""_pi(); // OK
float  operator ""_e(const char*); // OK
// エラー: サフィックスはアンダースコアで始まる必要がある
float operator ""Z(const char*);
// エラー: アンダースコアに続いて大文字で始まる名前は予約されている
// (注: "" と _ の間にスペースがある)
double operator"" _Z(long double);
// OK。注: "" と _ の間にスペースがない
double operator""_Z(long double);
// OK: リテラル演算子はオーバーロード可能
double operator ""_Z(const char* args);
int main() {}

注記

ユーザー定義リテラルの導入以来、固定幅整数型の フォーマットマクロ定数 を前の文字列リテラルの直後にスペースなしで使用するコードは無効となりました: std:: printf ( "%" PRId64 " \n " , INT64_MIN ) ; は以下のように置き換える必要があります std:: printf ( "%" PRId64 " \n " , INT64_MIN ) ;

maximal munch のため、ユーザー定義の整数リテラルおよび浮動小数点リテラルが p , P , (C++17以降) e および E で終わり、その後に演算子 + または - が続く場合、ソースコード内で演算子とは空白または括弧で区切る必要があります:

long double operator""_E(long double);
long double operator""_a(long double);
int operator""_p(unsigned long long);
auto x = 1.0_E+2.0;   // エラー
auto y = 1.0_a+2.0;   // OK
auto z = 1.0_E +2.0;  // OK
auto q = (1.0_E)+2.0; // OK
auto w = 1_p+2;       // エラー
auto u = 1_p +2;      // OK

整数または浮動小数点ユーザー定義リテラルに続くドット演算子についても同様です:

#include <chrono>
using namespace std::literals;
auto a = 4s.count();   // エラー
auto b = 4s .count();  // OK
auto c = (4s).count(); // OK

そうでなければ、単一の無効なプリプロセス数値トークン(例: 1.0 _E + 2.0 または 4s. count )が形成され、コンパイルが失敗する原因となります。

機能テストマクロ 規格 機能
__cpp_user_defined_literals 200809L (C++11) User-defined literals

キーワード

operator

#include <algorithm>
#include <cstddef>
#include <iostream>
#include <numbers>
#include <string>
// 度(入力パラメータ)からラジアン(戻り値)への変換に使用
constexpr long double operator""_deg_to_rad(long double deg)
{
    long double radians = deg * std::numbers::pi_v<long double> / 180;
    return radians;
}
// カスタム型で使用
struct mytype
{
    unsigned long long m;
};
constexpr mytype operator""_mytype(unsigned long long n)
{
    return mytype{n};
}
// 副作用のために使用
void operator""_print(const char* str)
{
    std::cout << str << '\n';
}
#if __cpp_nontype_template_args < 201911
std::string operator""_x2 (const char* str, std::size_t)
{
    return std::string{str} + str;
}
#else // C++20 文字列リテラル演算子テンプレート
template<std::size_t N>
struct DoubleString
{
    char p[N + N - 1]{};
    constexpr DoubleString(char const(&pp)[N])
    {
        std::ranges::copy(pp, p);
        std::ranges::copy(pp, p + N - 1);
    }
};
template<DoubleString A>
constexpr auto operator""_x2()
{
    return A.p;
}
#endif // C++20
int main()
{
    double x_rad = 90.0_deg_to_rad;
    std::cout << std::fixed << x_rad << '\n';
    mytype y = 123_mytype;
    std::cout << y.m << '\n';
    0x123ABC_print;
    std::cout << "abc"_x2 << '\n';
}

出力:

1.570796
123
0x123ABC
abcabc

標準ライブラリ

以下のリテラル演算子は標準ライブラリで定義されています:

インライン名前空間で定義 std::literals::complex_literals
純虚数を表す std::complex リテラル
(関数)
インライン名前空間で定義 std::literals::chrono_literals
時間を表す std::chrono::duration リテラル
(関数)
分を表す std::chrono::duration リテラル
(関数)
秒を表す std::chrono::duration リテラル
(関数)
ミリ秒を表す std::chrono::duration リテラル
(関数)
マイクロ秒を表す std::chrono::duration リテラル
(関数)
ナノ秒を表す std::chrono::duration リテラル
(関数)
特定の年を表す std::chrono::year リテラル
(関数)
月の日を表す std::chrono::day リテラル
(関数)
インライン名前空間で定義 std::literals::string_literals
文字配列リテラルを basic_string に変換
(関数)
インライン名前空間で定義 std::literals::string_view_literals
文字配列リテラルの文字列ビューを作成
(関数)

不具合報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
CWG 1473 C++11 リテラル演算子の宣言において、 "" ud-suffix の間の空白が
必須であった
任意とした
CWG 1479 C++11 リテラル演算子がデフォルト引数を持つことができた 禁止
CWG 2521 C++11 operator "" _Bq は、予約識別子 _Bq を使用するため
不適格(診断不要)であった
"" ud-suffix の間に空白があるリテラル演算子構文を
非推奨とした