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

2022-05-16 00:00:00 c++ c++20 user-defined-literals
什么是C++20的字符串文字运算符模板?在这方面,CpPreferences的example相当简明,我不是很清楚:

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

template<A a> A operator ""_a(); 

在尝试理解此功能时,我刚刚了解到在C++中可以使用数值文字运算符模板,它使数值常量的每一位都作为非类型参数传递给模板(参见。更好的解释here)。目前,文字运算符模板不能处理字符文字,尽管有支持这一功能的编译器扩展。我不认为C++20的字符串模板与此有任何关系,因为我了解到,扩展文本运算符模板以使用字符文字的提议在委员会中被否决了?


解决方案

有两个独立的提案:

  • 允许字符串文字作为非类型模板参数(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

然而,第一个方案中扩展文字运算符的部分被合并到第二个方案[lex.ext]/5:

如果S包含带有非类型模板参数的文字运算符模板,且字符串是格式良好的模板参数,则文字L被视为以下形式的调用 operator "" X<str>()

所以使用这个:

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

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


请注意,这些规则略有变化,因为根据P1185,默认的<=>要求将更改为默认的==要求。

相关文章