views:

209

answers:

1

I just found that when it comes to templates this code compiles in g++ 3.4.2 and works unless m() is not called:

template <typename T>
class C
{
     T e;

     public:
      C(): e(0) {};

 void m()
 {
        e = 0;
 };
 };

Now one may create and use instance

C<const int> c;

Until c.m() is not called there are no compile errors but is this legal?

+11  A: 

Yes, this is legal. The template specification is that until a method is instantiated, it doesn't exist and therefor is not checked by the compiler. Here's the relevant bit from the spec:

14.7.1 - Implicit instantiation

-9- An implementation shall not implicitly instantiate a function 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.

Don Neufeld
Broadly correct but to be more precise, it should speak about a method being instantiated, rather than invoked. Apart from invoking it, taking a member pointer to it will also do it; and if a method is virtual, it's implementation-defined whether instantiation is deferred or not.
Pavel Minaev
At least anything dependent on the template type. There is some confusion with non-dependent errors. E.g VC++ would accept even complete gibberish in the method as long as you don't invoke it (`non-sense here;`), however other compilers won't accept that even if you don't instantiate the template at all (which is probably more correct).
UncleBens
Anyone knows what's the intention of standard? I don't need for example to specialize code for const version of template at least at current level of my app (probably I will in future for the clarity). But is this a case?
doc
Steve Jessop
The Standard says that a template is ill-formed if no valid specialization can ever be generated out of it, but it says emitting a diagnostic is not required. In this case, however, "T" could be non-const, so the compiler cannot just emit an error for the template. And even if you would write "T const c;" as the member, it could be a class-type with a const "operator=".
Johannes Schaub - litb
You're right, in my example it's not the template member function which is wrong, it's the code which calls it. Oops.
Steve Jessop