Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是C++;用户定义的文字中是否允许使用14位分隔符?_C++_C++14_Language Lawyer_User Defined Literals_Digit Separator - Fatal编程技术网

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

C++ 是C++;用户定义的文字中是否允许使用14位分隔符?,c++,c++14,language-lawyer,user-defined-literals,digit-separator,C++,C++14,Language Lawyer,User Defined Literals,Digit Separator,当clang编译下一行时,g++6.1抱怨数字分隔符(请参阅): 根据C++14标准(N3796),哪种编译器(如果有的话)是正确的 否则,允许数字分隔符(§2.14.2)只是库(§20.12.5.8)的用户定义文字(§2.14.8)中的一个实现细节吗?IMHO不应该是,因为这些文字是在无符号long-long参数上定义的 我记得Howard Hinnant在他的演讲中(大约42分钟时)使用了10'000s作为例子 (请注意,我并不打算编写“1分23秒”的代码,因为八进制文字0123是64+1

当clang编译下一行时,g++6.1抱怨数字分隔符(请参阅):

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

否则,允许数字分隔符(§2.14.2)只是
库(§20.12.5.8)的用户定义文字(§2.14.8)中的一个实现细节吗?IMHO不应该是,因为这些文字是在
无符号long-long
参数上定义的

我记得Howard Hinnant在他的演讲中(大约42分钟时)使用了
10'000s
作为例子


(请注意,我并不打算编写“1分23秒”的代码,因为八进制文字0123是64+16+3==83,因此,我应该编写此代码

auto time = 1min + 23s;

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

如果你看一下语法,用户定义的整数文字可以是八进制文字ud后缀,八进制文字可以定义为
0
或八进制文字“opt-octal digital”

N4140§2.14.8

用户定义文字:

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

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

N4140§2.14.2

八进制文字:

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

因此
01的23s
是一个完全有效的文本。

WLOG表示十进制文本:

:

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

:

十进制文字:
非零位
十进制文字
'
opt 数字


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

正如@Aaron McDaid所建议的,这似乎是GCC实现
库的一个缺陷。存在(当前未确认)错误报告:

GCC的libstdc++为
std::chrono_文本实现了两个签名:

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...>(); }
标题(我的本地安装)中会出现错误

然而,GCC的库实现者可能故意忽略了这个版本,所以他们可以防止不需要的无符号到有符号的转换,因为秒被定义为

typedef duration<int64_t> seconds;
typedef持续时间秒;

编辑:

正如Jonathan Wakely最近在bug报告的评论中指出的, 该实现是通过设计结合
,但未考虑数字分隔符。

这似乎是库错误,应报告。我有限的实验表明,
libstdc++
定义了错误的文本运算符,使用了模板非类型参数
template
,而不是
unsigned long
。但这并不是标准所要求的,这是错误的。他们省略了
运算符“”s(unsigned long)
运算符,我认为这是基本的基本问题。(根据需要,他们确实有
运算符“”s(长双)
)这里报告了错误:(其他人发布了此链接,然后删除了他们的评论,但我认为这是正确的链接!)@Aaron McDaid:我删除了该评论,将其包括在我自己的答案中(见下文)。问题是标准要求编译时溢出检查,但是使用熟的文本运算符不允许这样做。我不明白什么是“熟的”运算符@t.C.。你是说“直接的”
unsigned long
重载不能在编译时进行检查吗?因此需要模板?@AaronMcDaid正确。“熟的”=取无符号长的;“raw”=接受字符的字符。
constexpr chrono::seconds
operator""s(unsigned long long __secs)
{ return chrono::seconds{__secs}; }
typedef duration<int64_t> seconds;