Было два отдельных предложения:
- Разрешение строковых литералов в качестве нетиповых параметров шаблона ( 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 содержит шаблон литерального оператора с нетиповым параметром шаблона, для которого str является правильно сформированным аргументом шаблона, литерал 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 .