Non-type template parameters are obviously ones that aren't types, for example:
template<int x>
void foo() { cout << x; }
There are other options than int
in that case, and I'd like to refer to this great answer.
Now, there's one thing that bugs me: structs. Consider:
struct Triple { int x, y, z; };
Triple t { 1, 2, 3 };
template<Triple const& t>
class Foo { };
Now, using normal nontype reference semantics, we can write:
Foo<t> f;
What's worth noting here is that t
can't be constexpr
or even const
, because that implies internal linkage, which basically means that the line won't compile. We can bypass that by declaring t
as const extern
. That itself might be a bit weird, but the one that really made me wonder was why this isn't possible:
Foo<Triple { 1, 2, 3 }> f;
We get a really decent error from compiler:
error:
Triple{1, 2, 3}
is not a valid template argument for typeconst Triple&
because it is not an lvalue.
We can't specify Triple
in template by value, because that's disallowed. However, I fail to understand the real problem with that small line of code. What's the reasoning behind not allowing using structs as value parameters. If I can use three int
s, why not a struct of three ints? If it has only trivial special members, it shouldn't be really different in handling than just three variables.