用户定义的文字后缀,带* _digit ......“?

时间:2011-04-25 11:43:56

标签: c++11 literals identifier user-defined-literals

C ++ 0x中的用户定义的文字后缀应该是标识符

  • _(下划线)(17.6.4.3.5)
  • 开头
  • 应该_开头,后跟大写字母(17.6.4.3.2)
      

    [...]以下划线后跟大写字母开头的每个名称都保留给实现以供任何使用。

  •   

有什么理由,为什么这样的后缀可能无法启动_ 后跟数字? I.E. _4_3musketeers

Musketeer dartagnan = "d'Artagnan"_3musketeers;
int num = 123123_4; // to be interpreted in base4 system?
string s = "gdDadndJdOhsl2"_64; // base64decoder

4 个答案:

答案 0 :(得分:1)

“可以” vs “可能” 可以表示可以表示许可的能力。

  

您是否有理由不能使用_后跟数字来启动用户定义的文字后缀?

许可意味着编码标准或最佳实践。您提供的示例似乎表明_\d如果使用正确(表示数字基础)将是精细后缀。不幸的是,你的问题无法得到深思熟虑的答案,因为没有人有这种新语言功能的经验。

要明确user-defined literal suffixes 可以_\d开头。

答案 1 :(得分:1)

_<number>形式的标识符的先例是std::placeholders(第20.8.9.1.3节)中的函数参数占位符对象机制,它定义了实现定义的此类符号的数量。

这是一件好事,因为这意味着用户无法#define该表单的任何标识符。 §17.6.4.3.1/ 1:

  

包含标准库标题的翻译单元不得在任何标准库标题中声明#define或#undef名称。

用户定义的文字函数的名称为operator "" _123,而不仅仅是_123,因此如果存在using namespace std::placeholders;,您的名称与库名称之间不会发生直接冲突。

我的2¢,你最好使用operator "" _baseconv并在文字"123123_4"_baseconv内对基数进行编码。

编辑: 查看Johannes(已删除)的答案,可能会担心_123可以用作宏 by实施。这当然是理论领域,因为这种预处理器的使用很难获得实现。此外,如果我没有弄错的话,在std::placeholders而不是std本身隐藏这些符号的原因是这些名称​​更多可能会被用户使用,例如包含Boost Bind(将它们隐藏在命名的命名空间内)。

令牌不保留供全球实施使用(17.6.4.3.2),并且有使用它们的先例,因此它们至少与forward一样安全。

答案 2 :(得分:1)

数字后跟下划线是合法的用户定义的文字后缀。 功能签名将是: operator“”_4(); 所以它不能被占位符吃掉。 文字将是单个预处理器令牌: 123123_4; 所以_4不会被占位符或预处理器符号破坏。

我对17.6.4.3.5的解读是,后缀不包含与实现或未来库添加的主要下划线风险冲突。它们还与现有的后缀碰撞:F,L,ULL等。用户定义文字的一个基本原理是新类型(例如小数)可以定义为纯库扩展,包括带有后缀d的文字, df,dl。

然后是风格和可读性的问题。就个人而言,我想我会忽略后缀1234_3;也许,也许不是。

最后,有一些想法没有让它成为标准(但我有点像)让_是像Ada和Ruby这样的数字的文字分隔符。所以你可以让123_456_789以视觉方式分离成千上万的例子。如果经历了后缀,你的后缀就会破裂。

答案 3 :(得分:1)

知道我有一些关于这个主题的论文: Digital Separators描述了使用_作为数字文字中的数字分隔符的提议

Ambiguity and Insecurity with User-Defined literals描述关于文字后缀命名和命名空间保留的想法的演变,以及针对未来数字分隔符消除用户定义文字冲突的努力。

对于_数字分隔符看起来不太好。

我有一个想法:数字分隔符的反斜杠或反引号怎么样?它不如_好,但只要反斜杠在数字流中,我就不认为会有任何碰撞。目前我所知,反引用没有词法用法。

i = 123\456\789;
j = 0xface\beef;

i = 123`456`789;
j = 0xface`beef;

这会留下_123作为文字后缀。