Consider the following code:
template <unsigned int N>
struct myclass
{
unsigned int f() {return N;}
unsigned int g() {static_assert(N > 0, ""); return N-1;}
};
Question: Do I have the guarantee that the following code will compile:
myclass<0> c;
c.f();
But the following will not:
myclass<0> c;
c.f();
c.g();
Yes, you have that guarantee. From [temp.inst]/11, emphasis mine:
An implementation shall not implicitly instantiate a function template, a variable template, a member template, a non-virtual member function, a member class, or a static data member of a class template that does not require instantiation.
If you don't call g()
, it doesn't require instantiation, so there should be no issues calling myclass<0>{}.f()
.
This is the same guarantee that lets you use std::vector
and std::map
with types that aren't default constructible as long as you don't do things like call resize()
and operator[]
, respectively.
A followup, as Jarod42 points out, is that explicitly instantiating myclass<0>
will produce the assert because, from [temp.explicit]/8:
An explicit instantiation that names a class template specialization is also an explicit instantiation of the same kind (declaration or definition) of each of its members (not including members inherited from base classes and members that are templates) that has not been previously explicitly specialized in the translation unit containing the explicit instantiation, except as described below.
The exceptions don't apply here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With