用户定义的文字是否允许C ++ 14位分隔符?

当clang编译以下代码时,g ++ 6.1会抱怨数字分隔符(请参阅Coliru上的实例 ):

auto time = 01'23s; 

哪个编译器(如果有的话)根据C ++ 14标准(N3796)是正确的?

否则,允许数字分隔符(§2.14.2)只是<chrono> chrono <chrono>库(§20.12.5.8)的用户定义文字(§2.14.8)中的实现细节? 恕我直言,它应该不是,因为这些文字是在unsigned long long参数上定义的。

我记得霍华德· 10'000s (Howard 10'000s在他的2016年CppCon演讲“A <chrono>年代<chrono>教程” (约42分钟的演讲)中以10'000s为例。


(请注意,我并不打算编码“1分23秒”,这只是偶然的 ,因为八进制文字0123是64 + 16 + 3 == 83。为了这个目的,我应该写

 auto time = 1min + 23s; 

但是这种可能的误导性解释不是问题的一部分。)

如果您查看语法,则用户定义的整数字面值可以是八进制文字的ud-suffix八进制文字可以定义为0八进制文字“ opt八进制数字”

N4140§2.14.8

用户定义的文字

  • 用户定义的整数字面
  • […]

用户定义的整数文字

  • 八进制文字ud后缀
  • […]

N4140§2.14.2

八进制文字

  • 0
  • 八进制文字' select八进制数字

所以01'23s是完全合法的文字。

WLOG十进制文字:

[lex.ext] :

用户定义的整数字面:
十进制文字 ud后缀

[lex.icon] :

十进制文字
非零数字
十进制文字' select数字

也就是说,UDL中允许使用数字分隔符。

这似乎是GCC执行<chrono> chrono <chrono>库时的一个错误,正如@Aaron McDaid所build议的。 有一个(目前未经证实的)错误报告: https : //gcc.gnu.org/bugzilla/show_bug.cgi?id = 69905

GCC的libstdc ++为std::chrono_literals实现了两个签名:

 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最近在错误报告的评论中指出的那样,这个实现是在devise时select了一个开放的图书馆工作组的问题 ,但没有考虑数字分隔符。