Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is C++20's string literal operator template?

What is C++20's string literal operator template? Cppreference's example in this respect is quite concise and not very clear to me:

struct A { A(const char *); auto operator<=>(const A&) const = default; };  template<A a> A operator ""_a();  

In trying to understand what this feature is I've just learned that you can have numeric literal operator templates in C++, which make each digit of numerical constant be passed as a non-type argument to a template (cf. a better explanation here). Currently, literal operator templates do not work with character literals, though there are compilers extensions enabling that. I don't think C++20's string literal operator templates have anything to do with that as I've learned that proposals to extend literal operator templates to work with character literals were voted down in the commitee?

like image 716
lukeg Avatar asked Jan 20 '19 15:01

lukeg


People also ask

What is a string literal in C?

A "string literal" is a sequence of characters from the source character set enclosed in double quotation marks (" "). String literals are used to represent a sequence of characters which, taken together, form a null-terminated string.

What is string literal with example?

A string literal is a sequence of zero or more characters enclosed within single quotation marks. The following are examples of string literals: 'Hello, world!' '10-NOV-91' 'He said, "Take it or leave it."'

What are the two types of string literals?

A string literal with the prefix L is a wide string literal. A string literal without the prefix L is an ordinary or narrow string literal. The type of narrow string literal is array of char .

How many types of string literals are there?

There are three sets of literal types available in TypeScript today: strings, numbers, and booleans; by using literal types you can allow an exact value which a string, number, or boolean must have.


1 Answers

There were two separate proposals:

  • Allowing string literals as non-type template parameters (P0424)
  • Allowing class types as non-type template parameters (P0732)

The first proposal was partially merged into the second. String literals still are not valid arguments as non-type template parameters, but they are valid arguments into class types. The example from [temp.arg.nontype]/4 might help:

template<class T, T p> class X {   /* ... */ };  X<const char*, "Studebaker"> x; // error: string literal as template-argument  const char p[] = "Vivisectionist"; X<const char*, p> y;            // OK  struct A {   constexpr A(const char*) {}   friend auto operator<=>(const A&, const A&) = default; };  X<A, "Pyrophoricity"> z;        // OK, string literal is a constructor argument to A 

However, the part of the first proposal which extended the literal operators was what was merged into the second, [lex.ext]/5:

If S contains a literal operator template with a non-type template parameter for which str is a well-formed template-argument, the literal L is treated as a call of the form operator "" X<str>()

So using this:

struct A { A(const char *); auto operator<=>(const A&) const = default; };      template<A a> A operator ""_a() { return a; } 

We can write "Hello"_a, which will be interpreted as calling operator "" _a<A("Hello")>.


Note that these rules are slightly in flux, as the defaulted <=> requirement will be changing to a defaulted == requirement as per P1185.

like image 106
Barry Avatar answered Sep 22 '22 10:09

Barry