My question is, whether the following code is valid:
template<int i> class Class
{
static_assert(sizeof(i) == 0, "Class instantiated with i != 1");
};
template<> class Class<1> {};
This snippet compiles with g++
. But clang++
is trapped by the static_assert
:
error: static_assert failed "Class instantiated with non-int type"
A template that uses a type instead of an int
like
template<typename T> class Class
{
static_assert(sizeof(T) == 0, "Class instantiated with non-int type");
};
template<> class Class<int> {};
is accepted by both compilers. Exactly the same pattern applies to function templates.
I found open-std.org::Non-dependent static_assert-declarations, but that does not seem to apply, because my static_assert
is dependent on the template parameter.
You may check the described behavior on godbolt.org
EDIT: As Johan Lundberg points out in the comment my question is wrong. Indeed sizeof(i)
does not depend on the template parameter. Also R.Sahu is completely right: It would make much more sense to assert i != 1
. For this again both compilers accept the code.
However, still the upper example compiles with g++
. As open-std.org::Non-dependent static_assert-declarations applies to that case (I apologize again for the wrong question in this respect): Is g++
actually wrong in compiling the code without error?
clang++ is right to reject your code, but g++ is not wrong to fail to catch the error; this is a "no diagnostic required" situation.
The Standard strictly defines expressions within a template as "type-dependent" and/or "value-dependent". Given template<int i>
, i
is value-dependent but not type-dependent.
[14.6.2.2/4]: Expressions of the following forms are never type-dependent (because the type of the expression cannot be dependent):
- ...
sizeof
unary-expression- ...
[14.6.2.3/2]: Expressions of the following form are value-dependent if the unary-expression or expression is type-dependent or the type-id is dependent:
sizeof
unary-expression- ...
So sizeof(i)
is not dependent.
Finally, 14.6/8 says:
If a hypothetical instantiation of a template immediately following its definition would be ill-formed due to a construct that does not depend on a template parameter, the program is ill-formed; no diagnostic is required.