3

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

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<'\''>. 它试图将'as传递char给我的模板template<char...CS> int operator"" _bin()!我用clang++-3.9msvc++-19.00尝试过,同样的抱怨,这真的让我怀疑。

我觉得这可能不是正确的行为。如果我的文字用引号括起来,我会理解的"1000'0000"_bin,但是模板运算符“”不存在这种形式,对吗?

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

更新1:如果'没问题:

可以将 digit-sep 用作各种事物的 sep,例如复数。'52.84'67.12_i' 对52.84+67.12i的行为会被很好地定义吗?

更新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

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

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

4

2 回答 2

4

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

模板整数文字定义为:

N4140 § 2.13.8 [lex.ext] / 3

否则(S包含文字运算符模板),L被视为形式的调用

operator "" X <’c1’, ’c2’, ... ’ck’&gt;()

其中n是源字符序列 c 1 c 2 ...c k。[注意:序列 c 1 c 2 ...c k只能包含来自基本源字符集的字符。——<em>尾注]

没有关于删除分隔符的消息。

于 2016-11-13T16:43:06.187 回答
0

正如我在这里所读到的那样,仅当您将文字作为数字获取时才允许使用分隔符,而不是当运算符是原始文字时。这意味着如果运算符参数类型是unsigned long long,则编译器将删除分隔符,而不是如果它是获取 C 字符串或字符的原始参数类型之一。

于 2016-11-13T16:47:55.013 回答