Что такое шаблон строкового литерала 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.