Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

static_assert depend on class template

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();
like image 431
Vincent Avatar asked Jun 11 '15 17:06

Vincent


1 Answers

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.

like image 89
Barry Avatar answered Nov 10 '22 19:11

Barry