用户定义字面值如何与数字分隔符一起使用



我只是修改了一个旧的代码示例,在用户定义的文本中添加了一个数字分隔符,由可变变量模板解析:

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.9msvc++-19.00,同样的抱怨,这真的让我怀疑。 我有一种感觉,那可能不是正确的行为。如果我的文字在引号中,比如"1000'0000"_bin,我会理解它,但这种形式不存在模板操作符",对吧?

我现在是否也期望在模板用户字面值操作符中使用数字分隔符' ?

更新1:'是ok的情况下:

可以用数字sep作为所有事物的sep,比如复数。52.84+67.12i的' 52.84'67.12_i'的行为是否定义良好?'

更新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的回答所暗示的,这似乎是Std的计划,所以人们可以依赖它。

就我所知,是的。如前所述,数字分隔符是用户定义的整数字面值的合法成员。

模板整型字面值定义为:

N4140§2.13.8 [lex.]/3

否则(S包含一个文字操作符模板),处理L作为

形式的调用
operator "" X <’c1’, ’c2’, ... ’ck’>()

其中n是源字符序列c1c2…ck。[备注:顺序C 1 C 2…C k只能包含字符从基本的源字符集。- 结束说明]

没有关于删除分隔符的词

就我在这里读到的情况而言,分隔符只允许在获得作为数字的文字时使用,而不允许在操作符是原始文字时使用。这意味着如果操作符参数类型为unsigned long long,则编译器将删除分隔符,而不是如果它是获得C-string或char的原始操作符之一。

最新更新