名前空間
変種
操作

ユーザー定義リテラル (C++11以降)

From cppreference.com
< cpp‎ | language
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 
 

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

目次

[編集] 構文

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

decimal-literal ud-suffix (1)
octal-literal ud-suffix (2)
hex-literal ud-suffix (3)
binary-literal ud-suffix (4)
fractional-constant exponent-part (オプション) ud-suffix (5)
digit-sequence exponent-part ud-suffix (6)
character-literal ud-suffix (7)
string-literal ud-suffix (8)
1-4) ユーザー定義整数リテラル、例: 12_km
5-6) ユーザー定義浮動小数点リテラル、例: 0.5_Pa
7) ユーザー定義文字リテラル、例: 'c'_X
8) ユーザー定義文字列リテラル、例: "abd"_L または u"xyz"_M
decimal-literal - 整数リテラルと同じで、0以外の10進数字の後に0個以上の10進数字が続く
octal-literal - 整数リテラルと同じで、0の後に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 - 文字列リテラルと同じで、生文字列リテラルを含む
ud-suffix - 識別子であり、リテラル演算子またはリテラル演算子テンプレートの宣言によって導入される (後述のリテラル演算子を参照)

整数および浮動小数点の数字シーケンスでは、任意の2つの数字の間にオプションの区切り文字 ' が許可されます。

(C++14以降)

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

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

1) ユーザー定義整数リテラルの場合、
a) オーバーロード集合にパラメータ型 unsigned long long のリテラル演算子が含まれる場合、ユーザー定義リテラル式は関数呼び出し operator ""X(n ULL) として扱われます。ここで nud-suffix のないリテラルです。
b) それ以外の場合、オーバーロード集合には、生リテラル演算子または数値リテラル演算子テンプレートのいずれか一方のみが含まれていなければなりません。オーバーロード集合に生リテラル演算子が含まれる場合、ユーザー定義リテラル式は関数呼び出し operator""X("n ") として扱われます。
c) それ以外の場合、オーバーロード集合に数値リテラル演算子テンプレートが含まれる場合、ユーザー定義リテラル式は関数呼び出し operator""X<'c1 ', 'c2 ', 'c3 '..., 'ck '>() として扱われます。ここで c1..ckn の個々の文字であり、それらはすべて基本文字集合に属しています。
2) ユーザー定義浮動小数点リテラルの場合、
a) オーバーロード集合にパラメータ型 long double のリテラル演算子が含まれる場合、ユーザー定義リテラル式は関数呼び出し operator ""X(f  L) として扱われます。ここで fud-suffix のないリテラルです。
b) それ以外の場合、オーバーロード集合には、生リテラル演算子または数値リテラル演算子テンプレートのいずれか一方のみが含まれていなければなりません。オーバーロード集合に生リテラル演算子が含まれる場合、ユーザー定義リテラル式は関数呼び出し operator ""X("f  ") として扱われます。
c) それ以外の場合、オーバーロード集合に数値リテラル演算子テンプレートが含まれる場合、ユーザー定義リテラル式は関数呼び出し operator""X<'c1 ', 'c2 ', 'c3 '..., 'ck '>() として扱われます。ここで c1..ckf の個々の文字であり、それらはすべて基本文字集合に属しています。
3) ユーザー定義文字列リテラルの場合、strud-suffix のないリテラルとします。
a) オーバーロード集合に、str が整形式テンプレート引数である非型テンプレートパラメータを持つ文字列リテラル演算子テンプレートが含まれる場合、ユーザー定義リテラル式は関数呼び出し operator ""X<str>() として扱われます。
(C++20以降)
b) それ以外の場合、ユーザー定義リテラル式は関数呼び出し operator ""X (str, len) として扱われます。ここで len は、終端のヌル文字を除く文字列リテラルの長さです。
4) ユーザー定義文字リテラルの場合、ユーザー定義リテラル式は関数呼び出し operator ""X(ch) として扱われます。ここで chud-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;    // calls operator ""_w(1.2L)
    u"one"_w; // calls operator ""_w(u"one", 3)
    12_w;     // calls operator ""_w("12")
    "two"_w;  // error: no applicable literal operator
}

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

int main()
{
    L"A" "B" "C"_x;  // OK: same as L"ABC"_x
    "P"_x "Q" "R"_y; // error: two different ud-suffixes (_x and _y)
}

[編集] リテラル演算子

ユーザー定義リテラルによって呼び出される関数は、リテラル演算子 (または、テンプレートの場合はリテラル演算子テンプレート) と呼ばれます。これは、以下の制限を除き、他の関数または関数テンプレートと同様に名前空間スコープで宣言されます (フレンド関数、関数テンプレートの明示的インスタンス化または特殊化、または using 宣言によって導入されることもあります)。

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

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

ud-suffix はアンダースコア _ で始まる必要があります。アンダースコアで始まらない接尾辞は、標準ライブラリによって提供されるリテラル演算子のために予約されています。また、二重アンダースコア __ を含めることはできません。そのような接尾辞も予約されています。

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

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

または、クラス型の非型テンプレートパラメータ (この場合、文字列リテラル演算子テンプレートとして知られます)。

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 言語リンケージは許可されません。

上記以外の制限として、リテラル演算子およびリテラル演算子テンプレートは通常の関数(および関数テンプレート)であり、inlineまたはconstexprで宣言でき、内部または外部リンケージを持ち、明示的に呼び出すことができ、アドレスを取得でき、その他もろもろです。

#include <string>
 
void        operator ""_km(long double); // OK, will be called for 1.0_km
void        operator "" _km(long double); // same as above, deprecated
std::string operator ""_i18n(const char*, std::size_t); // OK
 
template<char...>
double operator ""_pi(); // OK
float  operator ""_e(const char*); // OK
 
// error: suffix must begin with underscore
float operator ""Z(const char*);
 
// error: all names that begin with underscore followed by uppercase
// letter are reserved (NOTE: a space between "" and _).
double operator"" _Z(long double);
 
// OK. NOTE: no space between "" and _.
double operator""_Z(long double);
 
// OK: literal operators can be overloaded
double operator ""_Z(const char* args);
 
int main() {}

[編集] 注記

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

最長一致のため、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;   // error
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;       // error
auto u = 1_p +2;      // OK

同じことが、整数または浮動小数点ユーザー定義リテラルに続くドット演算子にも当てはまります。

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

さもなければ、単一の無効なプリプロセス数トークン(例: 1.0_E+2.04s.count)が形成され、コンパイルエラーとなります。

機能テストマクロ 規格 機能
__cpp_user_defined_literals 200809L (C++11) ユーザー定義リテラル

[編集] キーワード

operator

[編集]

#include <algorithm>
#include <cstddef>
#include <iostream>
#include <numbers>
#include <string>
 
// used as conversion from degrees (input param) to radians (returned output)
constexpr long double operator""_deg_to_rad(long double deg)
{
    long double radians = deg * std::numbers::pi_v<long double> / 180;
    return radians;
}
 
// used with custom type
struct mytype
{
    unsigned long long m;
};
 
constexpr mytype operator""_mytype(unsigned long long n)
{
    return mytype{n};
}
 
// used for side-effects
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 string literal operator template
 
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 に変換する
(function) [編集]
インライン名前空間 std::literals::string_view_literals で定義されています。
文字配列リテラルのstring viewを作成する
(function) [編集]

[編集] 欠陥報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
CWG 1473 C++11 ""ud-suffix の間の空白は
リテラル演算子の宣言で必須だった
オプションになった
CWG 1479 C++11 リテラル演算子はデフォルト引数を持つことができた 禁止された
CWG 2521 C++11 operator"" _Bq は予約済み識別子 _Bq を使用しているため、不適格だった(診断
は必須ではなかった)
リテラル演算子の構文を非推奨化
""ud-suffix の間の空白を持つ
English 日本語 中文(简体) 中文(繁體)