Can string-based user-defined literals be strongly typed?

1.2k views Asked by At

The new user-defined literal concept in C++ suggests some very interesting uses of string-literals, such as:

"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;

However, when I build these kinds of constructs in gcc, e.g.:

template <char... Chars> Name<Chars...> operator "" _name() {
    return Name<Chars...>();
}

auto a = 123_name;    // OK
auto b = "abc"_name;  // Error

I get the following error:

…unable to find string literal operator ‘operator"" _name’ with ‘const char [4]’, ‘long unsigned int’ arguments

From reading around, I'm guessing that the variadic-template form is not available to UDLs derived from string literals.

  1. Is it in fact the case that string literals cannot be resolved using the variadic template form?
  2. If so, does anyone have any insight into why such a useful form of UDL was left out of the standard?
2

There are 2 answers

4
R. Martinho Fernandes On BEST ANSWER

You are right. String literals cannot be used with the variadic template form (§2.14.8/5):

If L is a user-defined-string-literal, let str be the literal without its ud-suffix and let len be the number of code units in str (i.e., its length excluding the terminating null character). The literal L is treated as a call of the form

operator "" X (str, len)

I have shuffled through the proposal papers (the latest of which I could find was N2750) and could not find an explanation for not allowing the use of the variadic template form.

0
Hristo Venev On

N3599, which allows this, has been implemented in gcc and clang.

template<class CharT, CharT... chars>
int operator ""_suffix(){
    return 42;
}