名前空間
変種
操作

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

提供: cppreference.com
< cpp‎ | language
 
 
C++言語
一般的なトピック
フロー制御
条件付き実行文
繰り返し文 (ループ)
ジャンプ文
関数
関数宣言
ラムダ関数宣言
inline 指定子
例外指定 (C++20未満)
noexcept 指定子 (C++11)
例外
名前空間
指定子
decltype (C++11)
auto (C++11)
alignas (C++11)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点
文字 - 文字列 - nullptr (C++11)
ユーザ定義 (C++11)
ユーティリティ
属性 (C++11)
typedef 宣言
型エイリアス宣言 (C++11)
キャスト
暗黙の変換 - 明示的な変換
static_cast - dynamic_cast
const_cast - reinterpret_cast
メモリ確保
クラス
クラス固有の関数特性
特別なメンバ関数
テンプレート
その他
 
一般
値カテゴリ (lvalue, rvalue, xvalue)
評価順序 (副作用完了点)
定数式
未評価式
一次式
ラムダ式(C++11)
リテラル
整数リテラル
浮動小数点リテラル
ブーリアンリテラル
文字リテラル および エスケープシーケンス
文字列リテラル
ヌルポインタリテラル(C++11)
ユーザ定義リテラル(C++11)
演算子
代入演算子: a=b, a+=b, a-=b, a*=b, a/=b, a%=b, a&=b, a|=b, a^=b, a<<=b, a>>=b
インクリメントとデクリメント: ++a, --a, a++, a--
算術演算子: +a, -a, a+b, a-b, a*b, a/b, a%b, ~a, a&b, a|b, a^b, a<<b, a>>b
論理演算子: a||b, a&&b, !a
比較演算子: a==b, a!=b, a<b, a>b, a<=b, a>=b, a<=>b(C++20)
メンバアクセス演算子: a[b], *a, &a, a->b, a.b, a->*b, a.*b
その他の演算子: a(...), a,b, a?b:c
デフォルト比較(C++20)
演算子の代替表現
優先順位と結合性
畳み込み式(C++17)
new 式
delete 式
throw 式
alignof
sizeof
sizeof...(C++11)
typeid
noexcept(C++11)
演算子オーバーロード
変換
暗黙の変換
const_cast
static_cast
reinterpret_cast
dynamic_cast
明示的な変換 (T)a, T(a)
ユーザ定義変換
 

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

目次

[編集] 構文

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

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"_Lu"xyz"_M など。
decimal-literal - 整数リテラルの場合と同様、ゼロ以外の10進数字にゼロ個以上の10進数字が続いたもの
octal-literal - 整数リテラルの場合と同様、ゼロにゼロ個以上の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 - リテラル演算子またはリテラル演算子テンプレート宣言 (後述) によって導入された識別子。 プログラムによって導入されるすべての ud-suffix はアンダースコア文字 _ で始まらなければなりません。 標準ライブラリの ud-suffix はアンダースコアで始まりません。
整数および浮動小数点の数字の並びでは、任意の2つの数字の間に任意に区切り文字 ' を入れても構いません。 それらは無視されます。 (C++14以上)

あるトークンがユーザ定義リテラルの構文にも普通のリテラルの構文にもマッチする場合、それは普通のリテラルであると仮定されます (つまり 123LLLL をオーバーロードすることはできません)。

コンパイラがユーザ定義接尾辞 X を持つユーザ定義リテラルに遭遇したとき、 operator "" X という名前の関数を探して非修飾名の名前探索が行われます。 この探索で宣言が見付からない場合、プログラムは ill-formed です。 そうでなければ、

1) ユーザ定義整数リテラルの場合、
a) オーバーロード集合に unsigned long long 型の引数を持つリテラル演算子が含まれていれば、ユーザ定義リテラル式は関数呼び出し operator "" X(nULL) として扱われます。 ただし n は ud-suffix を取り除いたリテラルです。
b) そうでなければ、オーバーロード集合には生リテラル演算子または数値リテラル演算子テンプレートのいずれかが含まれていなければならず、しかし両方が含まれていてはなりません。 オーバーロード集合に生リテラル演算子が含まれている場合、ユーザ定義リテラル式は関数呼び出し operator "" X("n") として扱われます。
c) そうでなく、オーバーロード集合に数値リテラル演算子テンプレートが含まれている場合、ユーザ定義リテラル式は関数呼び出し operator "" X<'c1', 'c2', 'c3'..., 'ck'>() として扱われます。 ただし c1..ck は n の個々の文字です。
2) ユーザ定義浮動小数点リテラルの場合、
a) オーバーロード集合に long double 型の引数を持つリテラル演算子が含まれていれば、ユーザ定義リテラル式は関数呼び出し operator "" X(fL) として扱われます。 ただし fud-suffix を取り除いたリテラルです。
b) そうでなければ、オーバーロード集合には生リテラル演算子または数値リテラル演算子テンプレートのいずれかが含まれていなければならず、しかし両方が含まれていてはなりません。 オーバーロード集合に生リテラル演算子が含まれている場合、ユーザ定義リテラル式は関数呼び出し operator "" X("f") として扱われます。
c) そうでなく、オーバーロード集合に数値リテラル演算子テンプレートが含まれている場合、ユーザ定義リテラル式は関数呼び出し operator "" X<'c1', 'c2', 'c3'..., 'ck'>() として扱われます。 ただし c1..ck は f の個々の文字です。
3) ユーザ定義文字列リテラルの場合、 strud-suffix を除いたリテラルとすると、
a) str が well-formed なテンプレート実引数である非型テンプレート引数をもつ文字列リテラル演算子テンプレートをオーバーロード集合が含む場合、ユーザ定義リテラル式は関数呼び出し 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; // operator "" _w(1.2L) を呼びます。
    u"one"_w; // operator "" _w(u"one", 3) を呼びます。
    12_w; // operator "" _w("12") を呼びます。
    "two"_w; // エラー。 適用可能なリテラル演算子がありません。
}

翻訳フェーズ6で文字列リテラルの連結が行われるとき、ユーザ定義リテラルも同様に連結されます。 ud-suffix は連結の目的に対しては無視されます。 ただし連結されたすべてのリテラルに対して現れてよい接尾辞はひとつだけです。

int main() {
    L"A" "B" "C"_x; // OK。 L"ABC"_x と同じ。
    "P"_x "Q" "R"_y;// エラー。 2つの異なる ud-suffix (_x と _y)。
}

[編集] リテラル演算子

ユーザ定義リテラルによって呼ばれる関数はリテラル演算子 (またはそれがテンプレートの場合はリテラル演算子テンプレート) と言います。 これは名前空間スコープの他の関数または関数テンプレートとまったく同様に宣言されます (フレンド関数や関数テンプレートの明示的実体化または特殊化であってもよく、または using 宣言によって導入されても構いません)。 ただし以下の制限があります。

この関数の名前は以下の2つの形式のいずれかです。

operator "" identifier
operator user-defined-string-literal (C++14以上)
identifier - この関数を呼ぶユーザ定義リテラルのための ud-suffix として使用する識別子。 アンダースコア _ で始まらなければなりません。 アンダースコアで始まらない接尾辞は標準ライブラリの提供するリテラル演算子用に予約されています��
user-defined-string-literal - 文字シーケンス ""ud-suffix になる文字シーケンスが空白なしで続いたもの。 この特別な構文は言語のキーワードおよび予約識別子を ud-suffix として使用することを可能とし、ヘッダ <complex>operator ""if の宣言で使用されています。 この形式を使用することはユーザ定義リテラル演算子がアンダースコアで始まらなければならないというルールを変えるものではないことに注意してください。 operator ""if のような宣言は標準ライブラリの一部としてのみ現れることができます。 しかし、これはアンダースコアに大文字が続いたもの (通常は予約識別子です) の使用を可能とします。

リテラル演算子がテンプレートの場合は、空の引数リストを持たなければならず、テンプレート引数をひとつだけ持つことができます。 このテンプレート引数は、以下のような要素型が char の非型テンプレートパラメータパック (この場合は数値リテラル演算子テンプレートと言います)

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

であるか、以下のようなクラス型の非型テンプレート引数 (この場合は文字列リテラル演算子テンプレートと言います)

struct A { A(const char *); auto operator<=>(const A&) const = default; };
 
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 として宣言したり、内部または外部リンケージを持たせたり、アドレスを取ったりできます。

void operator "" _km(long double); // OK。 1.0_km に対して呼ばれます。
std::string operator "" _i18n(const char*, std::size_t); // OK
template <char...> double operator ""(); // OK
float operator ""_e(const char*); // OK
 
float operator ""Z(const char*); // エラー。 接尾辞はアンダースコアで始まらなければなりません。
double operator"" _Z(long double); // エラー。 アンダースコアと大文字で始まる名前はすべて
                                   // 予約されています。
double operator""_Z(long double); // OK。 _Z が予約されていても ""_Z は使用できます。

[編集] ノート

ユーザ定義リテラルが導入されたため、先行する文字列リテラルの後に空白がない固定幅の整数型のためのマクロ定数を使用するコードは無効になります。 例えば std::printf("%"PRId64"\n",INT64_MIN);std::printf("%" PRId64"\n",INT64_MIN); に置き換える必要があります。

最長一致のために、 eEp および P (C++17以上) で終わるユーザ定義の整数および浮動小数点リテラルは、演算子 + または - が続くときは、ソースコード上でホワイトスペースまたは括弧で演算子を分離しなければなりません。

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.04s.count など) が形成され、コンパイルが失敗する原因になります。

[編集]

#include <iostream>
 
// 変換のために使用します
constexpr long double operator"" _deg ( long double deg )
{
    return deg * 3.14159265358979323846264L / 180;
}
 
// カスタム型のために使用します
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;
}
 
int main(){
    double x = 90.0_deg;
    std::cout << std::fixed << x << '\n';
    mytype y = 123_mytype;
    std::cout << y.m << '\n';
    0x123ABC_print;
}

出力:

1.570796
123
0x123ABC

[編集] 標準ライブラリ

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

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