Можно ли строго типизировать пользовательские литералы на основе строк?
Новая пользовательская концепция литералов в C++ предлагает несколько очень интересных способов использования строковых литералов, таких как:
"Goodbye %s world"_fmt("cruel");
"Goodbye %s world"_fmt(123); // Error: arg 1 must be convertible to const char*
R"(point = \((\d+), (\d+)\))"_re; // Builds DFA at compile-time.
typedef table<
column<"CustId"_name , std::string>,
column<"FirstName"_name, std::string>,
column<"LastName"_name , std::string>,
column<"DOB"_name , date >
> Customer;
Тем не менее, когда я строю такие виды конструкций в GCC, например:
template <char... Chars> Name<Chars...> operator "" _name() {
return Name<Chars...>();
}
auto a = 123_name; // OK
auto b = "abc"_name; // Error
Я получаю следующую ошибку:
…unable to find string literal operator ‘operator"" _name’ with ‘const char [4]’, ‘long unsigned int’ arguments
Из прочтения я догадываюсь, что форма шаблона variadic недоступна для UDL, полученных из строковых литералов.
- Действительно ли это так, что строковые литералы не могут быть разрешены с использованием формы шаблона variadic?
- Если да, есть ли у кого-нибудь понимание, почему такая полезная форма UDL осталась вне стандарта?
2 ответа
Вы правы. Строковые литералы нельзя использовать с шаблоном с переменным шаблоном (§2.14.8/5):
Если
L
является определяемым пользователем строковым литералом, пусть str будет литералом без его ud-суффикса, и пусть len будет количеством единиц кода в str (т. е. его длина исключает завершающий нулевой символ). БуквальныйL
трактуется как вызов формыoperator "" X (str, len)
Я перетасовал документы с предложениями (последний из которых я смог найти - N2750) и не смог найти объяснения тому, как не разрешить использование формы бланка.
N3599, который позволяет это, был реализован в gcc и clang.
template<class CharT, CharT... chars>
int operator ""_suffix(){
return 42;
}