Ren*_*ter 42 c++ language-lawyer user-defined-literals c++14 digit-separator
当clang编译以下行时,g ++ 6.1会抱怨数字分隔符(请参阅Coliru上的实例):
auto time = 01'23s;
Run Code Online (Sandbox Code Playgroud)
根据C++ 14标准(N3796),哪个编译器(如果有)是正确的?
否则,允许数字分隔符(§2.14.2)只是<chrono>
库的用户定义文字(§2.14.8)中的实现细节(§20.12.5.8)?恕我直言,它应该不是,因为这些文字是在unsigned long long
参数上定义的.
我记得Howard Hinnant10'000s
在他的CppCon 2016演讲"A <chrono>
tutorial"(在他的演讲中大约42分钟)中作为一个例子.
(请注意,我不打算编码"1分23秒",这只是偶然的,因为八进制文字0123是64 + 16 + 3 == 83.为此我应该写
auto time = 1min + 23s;
Run Code Online (Sandbox Code Playgroud)
但是这种可能误导性的解释不是问题的一部分.)
krz*_*zaq 19
如果你看一下语法,用户定义的整数字面可以八进制字面UD-后缀,和八进制文字被定义为0
或八进制字符' 选择八进制数字.
N4140§2.14.8
user-defined-literal:
- 用户定义的整数字面
- [...]
user-defined-integer-literal:
- 八进制文字ud后缀
- [...]
N4140§2.14.2
八进制:
0
- 八进制' 选择八进制数字
这01'23s
是一个完全有效的文字.
用于十进制文字的WLOG:
user-defined-integer-literal:
decimal-literal ud-suffix
decimal-literal:
非零位
十进制文字的’
opt 数字
也就是说,UDL中允许使用数字分隔符.
<chrono>
正如@Aaron McDaid建议的那样,这似乎是GCC实施图书馆的一个错误.有一个(目前未经证实的)错误报告: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...>(); }
Run Code Online (Sandbox Code Playgroud)
标准不要求提供错误的模板版本.添加时
constexpr chrono::seconds
operator""s(unsigned long long __secs)
{ return chrono::seconds{__secs}; }
Run Code Online (Sandbox Code Playgroud)
到<chrono>
标题(我的本地安装)错误消失.
但是,GCC的库实现者可能故意省略了这个版本,因此它们可以防止不需要的无符号签名转换,因为秒被定义为
typedef duration<int64_t> seconds;
Run Code Online (Sandbox Code Playgroud)
编辑:
正如Jonathan Wakely最近在错误报告的评论中指出的那样,实施是通过设计选择与 开放式图书馆工作组问题相关联的,但没有考虑数字分隔符.
归档时间: |
|
查看次数: |
2410 次 |
最近记录: |