Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When and how to use a template literal operator?

On cppreference there is a mentioning that one can have templated user-literal operators, with some restrictions:

If the literal operator is a template, it must have an empty parameter list and can have only one template parameter, which must be a non-type template parameter pack with element type char, such as

template <char...> double operator "" _x();

So I wrote one like in the code below:

template <char...> 
double operator "" _x()
{
    return .42;
}

int main()
{
    10_x; // empty template list, how to specify non-empty template parameters?
}

Question:

  1. The code works, but how can I use the operator with some non-empty template parameters? 10_x<'a'>; or 10_<'a'>x; does not compile.
  2. Do you have any example of real-world usage of such templated operators?
like image 582
vsoftco Avatar asked Sep 30 '16 16:09

vsoftco


1 Answers

10_x; // empty template list, how to specify non-empty template parameters?

That isn't quite right. The template parameter list isn't empty. When you write:

template <char... Cs> 
??? operator "" _x()

The Cs get populated from the stuff on the left-hand side of the literal. That is, when you write:

10_x

that calls:

operator ""_x<'1', '0'>();

One simple example would be to build a compile time, overflow-safe binary literal such that:

template <uint64_t V>
constexpr uint64_t make_binary() {
    return V;
}

template <uint64_t V, char C, char... Cs>
constexpr uint64_t make_binary() {
    static_assert(C == '0' || C == '1', "invalid binary");

    return make_binary<2*V + C - '0', Cs...>();
}

template <char... Cs> 
uint64_t operator "" _b()
{
    static_assert(sizeof...(Cs) <= 64, "overflow");

    return make_binary<0, Cs...>();
}

uint64_t a = 101_b; // OK: a == 5
uint64_t b = 102_b; // error: invalid
uint64_t c = 11111111110000000000111111111100000000001111111111000000000011111111110000000000_b; // error: overflow
like image 156
Barry Avatar answered Oct 26 '22 22:10

Barry