Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?
like image 639
Marcelo Cantos Avatar asked Jun 04 '12 11:06

Marcelo Cantos


People also ask

What is data type of string literal?

String literals are specified by one or more characters enclosed in single quotes. The default data type for string literals is varchar, but a string literal can be assigned to any character data type or to money or date data type without using a data type conversion function.

What is a user-defined literal?

In a raw user-defined literal, the operator that you define accepts the literal as a sequence of char values. It's up to you to interpret that sequence as a number or string or other type. In the list of operators shown earlier in this page, _r and _t can be used to define raw literals: C++ Copy.

Is string a literal type C++?

In C++, an ordinary string literal has type 'array of n const char'. For example, The type of the string literal "Hello" is "array of 6 const char". It can, however, be converted to a const char* by array-to-pointer conversion.

What is string literal operator?

A string literal or anonymous string is a string value in the source code of a computer program. Modern programming languages commonly use a quoted sequence of characters, formally "bracketed delimiters", as in x = "foo" , where "foo" is a string literal with value foo .


2 Answers

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.

like image 115
R. Martinho Fernandes Avatar answered Oct 19 '22 02:10

R. Martinho Fernandes


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

template<class CharT, CharT... chars>
int operator ""_suffix(){
    return 42;
}
like image 40
Hristo Venev Avatar answered Oct 19 '22 02:10

Hristo Venev