Можно ли строго набирать строковые пользовательские литералы?
Новая определяемая пользователем буквальная концепция в С++ предлагает некоторые очень интересные применения строковых литералов, например:
"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
Отчитываясь, я предполагаю, что форма вариационного шаблона недоступна для UDL, полученных из строковых литералов.
- Действительно ли это, что строковые литералы не могут быть решены с использованием формы вариационного шаблона?
- Если да, то кто-нибудь может понять, почему такая полезная форма UDL была оставлена вне стандарта?
Ответы
Ответ 1
Вы правы. Строковые литералы не могут использоваться с формой вариационного шаблона (§2.14.8/5):
Если L
является определяемым пользователем строковым литералом, пусть str является литералом без его ud-суффикса и пусть len - количество кодовых единиц в str (т.е. его длина, исключая конечный нулевой символ). Литерал L
рассматривается как вызов формы
operator "" X (str, len)
Я перетасовал документы предложений (последний из которых я мог найти, был N2750) и не смог найти объяснения, что не позволял использовать вариационная форма шаблона.
Ответ 2
N3599, который позволяет это, был реализован в gcc и clang.
template<class CharT, CharT... chars>
int operator ""_suffix(){
return 42;
}