什么是C++ 20的字符串文字运算符模板?

luk*_*keg 21 c++ user-defined-literals c++20

什么是C++ 20的字符串文字运算符模板?Cppreference 在这方面的例子非常简洁,对我来说不是很清楚:

struct A { A(const char *); auto operator<=>(const A&) const = default; };

template<A a> A operator ""_a(); 
Run Code Online (Sandbox Code Playgroud)

在试图理解这个特性是什么时,我刚学会了你可以在C++中使用数字文字运算符模板,这使得数字常量的每个数字都作为非类型参数传递给模板(参见这里更好的解释) .目前,文字运算符模板不支持字符文字,尽管有编译器扩展可以实现这一点.我不认为C++ 20的 字符串文字运算符模板与此有关,因为我已经了解到扩展文字运算符模板以处理字符文字的提议在委员会中被否决了?

Bar*_*rry 21

有两个单独的提案:

  • 允许字符串文字作为非类型模板参数(P0424)
  • 允许类类型作为非类型模板参数(P0732)

第一个提案部分合并到第二个提案.字符串文字仍然不是有效的参数作为非类型模板参数,但它们是类类型的有效参数.[temp.arg.nontype]/4中的示例可能会有所帮助:

template<class T, T p> class X {
  /* ... */
};

X<const char*, "Studebaker"> x; // error: string literal as template-argument

const char p[] = "Vivisectionist";
X<const char*, p> y;            // OK

struct A {
  constexpr A(const char*) {}
  friend auto operator<=>(const A&, const A&) = default;
};

X<A, "Pyrophoricity"> z;        // OK, string literal is a constructor argument to A
Run Code Online (Sandbox Code Playgroud)

但是,扩展文字运算符的第一个提案的部分是合并到第二个,[lex.ext]/5:

如果S包含带有非类型模板参数的文字运算符模板,其中str是格式正确的模板参数,则文字L被视为表单的调用 operator "" X<str>()

所以用这个:

struct A { A(const char *); auto operator<=>(const A&) const = default; };     
template<A a> A operator ""_a() { return a; }
Run Code Online (Sandbox Code Playgroud)

我们可以写"Hello"_a,这将被解释为调用operator "" _a<A("Hello")>.


请注意,这些规则略有不同,因为违约<=>要求将==根据P1185更改为默认要求.