用户定义的文字如何与数字分隔符一起使用?

时间:2016-11-13 16:33:11

标签: c++ variadic-templates user-defined-literals digit-separator

我只是通过向用户定义的文字添加数字分隔符来修改我的代码的旧示例,由可变参数模板解析:

namespace lits {
  // helper for 1 arg
  template<char C> int bin();  // common
  template<>       int bin<'1'>() { return 1; } // spec.
  template<>       int bin<'0'>() { return 0; } // spec.
  // helper 2 or more args
  template<char C, char D, char... ES>
  int bin() {
    return bin<C>() << (sizeof...(ES)+1) | bin<D,ES...>() ;
  }
  // operator"" _bin
  template<char...CS> int operator"" _bin()
    { return bin<CS...>(); };
}
int main() {
  using namespace lits;
  int number = 1000'0000_bin; // <<< I added a ' here
}

男孩,当 g ++ 6.2.0 试图实例化bin<'\''>时,我感到很惊讶。它试图将'作为char传递给我的模板template<char...CS> int operator"" _bin()!我尝试用 clang ++ - 3.9 msvc ++ - 19.00 ,同样的抱怨,这让我持怀疑态度。

我觉得这可能不是正确的行为。如果我的文字是引号,我会理解它,比如说"1000'0000"_bin,但这个表格对于模板运算符不存在&#34;&#34;,对吧?

我现在也希望模板中的数字分隔符'是用户文字运算符吗?

更新1:以防'正常:

可以使用digit-sep作为所有类型的东西的sep,比如复数。 '52.84&#39; 67.12_i&#39;的行为会不会 52.84 + 67.12i 的定义是否明确?&#39;

Udpdate 2:作为反应的一些评论。以下编译:

#include <iostream>
#include <string>
using std::string;

namespace lits {
  // helper
  template<char C> string sx() { return string{}+C; }
  // helper 2 or more args
  template<char C, char D, char... ES>
  string sx() {
    return sx<C>() + sx<D,ES...>();
  }
  // operator"" _sx
  template<char...CS> string operator"" _sx()
  { return sx<CS...>(); };
}
int main() {
  using namespace lits;
  std::cout << 10000000_sx << '\n';
  std::cout << 10'000'000_sx << '\n';
  std::cout << 0x00af_sx << '\n';
  std::cout << 0x0'c'0'a'f_sx << '\n';
  std::cout << 007_sx << '\n';
  std::cout << 0b01_sx << '\n';
  // the following do not work:
  //std::cout << 0b0a8sh3s1_sx << '\n';
  //std::cout << "abcde"_sx << '\n';
}

输出是:

10000000
10'000'000
0x00af
0x0'c'0'a'f
007
0b01

这意味着模板所有字符:前缀和数字分隔符 - 所有这些。 (克++ - 6.2.0)

正如@ krzaq的回答所示,这似乎是Std的计划,所以人们可以依赖它。

2 个答案:

答案 0 :(得分:4)

据我所知,是的。正如here所解释的,数字分隔符是用户定义的整数文字的合法成员。

模板整数文字定义为:

  

N4140§2.13.8[lex.ext] / 3

     

否则( S 包含文字运算符模板), L 被处理   作为表格的调用

operator "" X <’c1’, ’c2’, ... ’ck’>()
     

其中 n 是源字符序列c 1 c 2 ... c k 。 [注意:序列   c 1 c 2 ... c k 只能包含字符   来自基本的源字符集。 - 结束记录]

没有关于删除分隔符的说法。

答案 1 :(得分:0)

尽管我阅读here,但只有当您将文字作为数字时才允许使用分隔符,而不是在运算符是原始文字时。这意味着如果运算符参数类型为unsigned long long,则编译器将删除分隔符,而不是它是获取C-string或char的原始类型之一。