1
votes

I'm using the following template to encode unsigned char values:

template <unsigned char val>
struct Cell {
    enum { value = val };

    using add = Cell<val + 1>;
    using sub = Cell<val - 1>;
};

I expected sub to behave like a standard unsigned char variable regarding overflow:

unsigned char x = 0;
x - 1; // 255

But instead I get a compiler error in Clang:

using cell = Cell<0>;
cell::sub::value; // Error here.


Non-type template argument evaluates to -1, which cannot be narrowed to type 'unsigned char'

Is overflow handled differently in template contexts?

1

1 Answers

2
votes

val - 1 is an int on your platform, on account of the usual arithmetic conversions. There is no sensible meaning for a template parameter of type unsigned char to be given an int argument.

Simply make sure that your template argument has the desired type:

using sub = Cell<static_cast<unsigned char>(val - 1U)>;
//               ^^^^^^^^^^^^^^^^^^^^^^^^^^       ^^

(Using an unsigned int literal means that the usual conversions produce an unsigned int, which has well-defined narrowing semantics.)