Clangが次の行をコンパイルしている間、g ++ 6.1は数字区切り文字について文句を言います( Coliruの実例 を参照):
auto time = 01'23s;
C++ 14標準(N3796)によると、どのコンパイラーが正しいですか?
それ以外の場合、数字区切り文字(§2.14.2)を許可するのは、<chrono>
ライブラリ(§20.12.5.8)のユーザー定義リテラル(§2.14.8)の実装の詳細だけですか?これらのリテラルはunsigned long long
パラメータで定義されているため、私見ではありません。
ハワード・ヒナントが例として10'000s
を使用したことを覚えています CppCon2016トーク "A <chrono>
チュートリアル" (彼のトークの約42分)。
(8進数のリテラル0123は偶然にのみ正しいである「1分23秒」をコーディングするつもりはなかったことに注意してください64 + 16 + 3 == 83。そのために私は書くべきです
auto time = 1min + 23s;
しかし、その考えられる誤解を招く解釈は問題の一部ではありません。)
文法を見ると、ser-defined-integer-literalはoctal-literal ud-suffixであり、octal-literalが定義されています。どちらかとして0
または8進数-リテラル ’opt 8進数。
N4140§2.14.8
ユーザー定義リテラル:
- ser-defined-integer-literal
- [...]
ser-defined-integer-literal:
- 8進数-リテラルのud-サフィックス
- [...]
N4140§2.14.2
8進数-リテラル:
0
- 8進数-リテラル ’opt 8進数
そう 01'23s
は完全に有効なリテラルです。
@Aaron McDaidが示唆したように、これはGCCの<chrono>
ライブラリの実装のバグのようです。 (現在未確認の)バグレポートがあります: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69905
GCCのlibstdc ++はstd::chrono_literals
の2つの署名を実装します:
constexpr chrono::duration<long double>
operator""s(long double __secs)
{ return chrono::duration<long double>{__secs}; }
template <char... _Digits>
constexpr chrono::seconds
operator""s()
{ return __check_overflow<chrono::seconds, _Digits...>(); }
エラーが発生するテンプレートバージョンは、標準では必要ありません。追加するとき
constexpr chrono::seconds
operator""s(unsigned long long __secs)
{ return chrono::seconds{__secs}; }
(私のローカルインストールの)<chrono>
ヘッダーに、エラーが消えます。
ただし、GCCのライブラリ実装者は、このバージョンを意図的に省略している可能性があります。秒は次のように定義されているため、不要な署名なしから署名付きへの変換を防ぐことができます。
typedef duration<int64_t> seconds;
編集:
Jonathan Wakelyがバグレポートのコメントで最近指摘したように、実装は open Library Working Group issue に関連して設計によって選択されましたが、桁区切り記号は考慮されていませんでした。
10進リテラルのWLOG:
user-defined-integer-literal:
decimal-literalud-suffix
decimal-literal:
ゼロ以外の数字
decimal-literal’
opt数字
つまりはい、UDLでは数字区切り記号を使用できます。