Что такое шаблон строкового литерала C++20?

Что такое шаблон строкового литерала C++20? Пример Cppreference в этом отношении довольно лаконичен и не очень понятен для меня:

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

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

Пытаясь понять, что это за функция, я только что узнал, что у вас могут быть шаблоны числовых литеральных операторов в C++, которые позволяют передавать каждую цифру числовой константы в качестве нетипичного аргумента в шаблон (см. Более подробное объяснение здесь), В настоящее время шаблоны литеральных операторов не работают с символьными литералами, хотя существуют расширения компиляторов, позволяющие это сделать. Я не думаю, что шаблоны строковых литералов оператора C++20 имеют какое-либо отношение к этому, так как я узнал, что предложения по расширению шаблонов литеральных операторов для работы с символьными литералами были отклонены в комитете?

1 ответ

Решение

Было два отдельных предложения:

  • Разрешение строковых литералов в качестве нетиповых параметров шаблона ( 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.

Другие вопросы по тегам