I use g++ 4.6.3, (currently default package for ubuntu 12.04) with the flag c++0x, and I stumble across this:
template <typename T>
inline T getValue(AnObject&)
{
static_assert(false , "this function has to be implemented for desired type");
}
with the compilation error:
static_assertion failed "this function has to be implemented for the desired type"
even though I don't call this function anywhere yet.
Is it a g++ bug ? Shouldn't this function be instanciated only if it is called somewhere in the code.
That's because the condition does not depend in any way on the template parameters. Therefore, the compiler can evaluate it even before instantiating that template, and produces the associated compilation error message if it the evaluation yields false
.
In other words, this is not a bug. Although many things can only be checked once a template is instantiated, there are other validity checks that a compiler can perform even before. This is why C++ has a two-phase name lookup, for instance. The compiler is just trying to help you finding errors that are 100% likely to occur.
Can you confirm that this function is instanciated even though I call it nowhere in the code ? Is that what you said ?
@StephaneRolland: The function is not instantiated, only the
static_assert()
instruction is executed.@StephaneRolland: I do not remember how Alexandrescu defined it, but that's very likely. After all, this is a new language feature, not just a library. Similarly, if you write a function call to
foo()
in your template functiongetValue()
, and no functionfoo()
exist, your code won't compile, because the compiler knows that there is no way you could instantiate that template in a way that it would compile.@StephaneRolland: then use
static_assert()
, but make the condition dependent on some template argument. Make it such that it will always yieldfalse
for the arguments you are going to instantiate it with (e.g.static_assert(typename is_same<T, type_false>::value), "Error!")
, but do mention the template argument in the condition. This will tell the compiler: "Hey, this is a dependent name, so wait until instantiation before judging..."@StephaneRolland: Note that
static_assert(sizeof(T) == 0, "Error!")
is usually brought up as another solution, but I think the concensus is that this can fail "early" as well, because the compiler can know the size is never less than 1 without even looking atT
. Just to keep that out there.