10

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?
Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
  • What exactly is useful about creating a new type for every literal, types that would be entirely distinct from one-another? – Nicol Bolas Jun 04 '12 at 15:11
  • @NicolBolas: In the examples shown, you *want* different literals to have different types. Moreover, the final type of a literal wouldn't necessarily be a naïve concatenation of its characters. For instance, `"freq: %g Hz" world"_fmt(44000)` might resolve to something like `Formatter("freq: ", " Hz")(44000)` by means of metaprogramming. – Marcelo Cantos Jun 04 '12 at 16:47
  • That would also mean that you *cannot* pass it something that isn't a number. So you couldn't pass it something that it might use `operator<<` to convert into a stream, thus removing the possibility of customizing data types. – Nicol Bolas Jun 04 '12 at 17:11
  • Nice examples of usage of user-defined literals. – Diego Sevilla Jun 04 '12 at 17:18
  • @NicolBolas: If you mean that the `%g` is too constraining, that's easily solvable: `"value(%<)"_fmt(t)` could resolve to something like `format("value(", stream_format(t), ")")`, which would in turn invoke `Formatter>("value(", ")")(t)`. – Marcelo Cantos Jun 04 '12 at 17:49

2 Answers2

8

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.

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
  • Could it be something as trivial as concurrent development of the two features which prevented one from using the other ? – Matthieu M. Jun 04 '12 at 13:11
  • @MatthieuM. I don't think so. I can't find evidence of them being developed separately (they're always together in the same paper). To be honest, when I saw the variadic form the very first thing that came to mind was the kind of ideas the OP showcases in the answer. I'd like to assume the committee saw some potential problem in this. Either that or an very annoying oversight. – R. Martinho Fernandes Jun 04 '12 at 14:22
  • 3
    All of the user defined literals that allow the use of the variadic form are limited to the basic source character set (simply because the grammar doesn't allow anything else in ints or floats). String literals don't have that limitation, so with a multibyte source/execution encoding you have c-chars in the string literal that may not be representable as individual chars. That might have something to do with the decision not to allow the variadic form with string literals. – bames53 Jun 04 '12 at 18:21
  • I think the committee saw the variadic form as an option for numeric literals that would admit compile-time evaluation. I think they were thinking "number" not string. – emsr Jun 06 '12 at 12:44
2

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

template<class CharT, CharT... chars>
int operator ""_suffix(){
    return 42;
}
Hristo Venev
  • 972
  • 5
  • 17