Можно ли строго типизировать пользовательские литералы на основе строк?

Новая пользовательская концепция литералов в 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, полученных из строковых литералов.

  1. Действительно ли это так, что строковые литералы не могут быть разрешены с использованием формы шаблона variadic?
  2. Если да, есть ли у кого-нибудь понимание, почему такая полезная форма 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;
}
Другие вопросы по тегам