Question

Well I got the following template (which contains a big error):

template <class FluxVar = IloIntVar, class FluxVarArray = IloIntVarArray, 
          class DelayVar = IloIntVar, class DelayVarArray = IloIntVarArray, 
          class LoadVar = IloIntVar, class LoadVarArray = IloIntVarArray,
          class BoolVar = IloBoolVar, class BoolVarArray = IloBoolVarArray>
class MyClass {
public:
    int getAlpha () { return m_alpha ; }
private:
    int m_alpha1 ; // See the "1" here
}

In my code, I do something like:

MyClass <> myClass1 ;
MyClass <IloNumVar, IloNumVarArray, IloNumVar, IloNumVarArray, IloNumVar, IloNumVarArray> myClass2 ;
MyClass <IloNumVar, IloNumVarArray, IloNumVar, IloNumVarArray, IloNumVar, IloNumVarArray, IloNumVar, IloNumVarArray> myClass3 ; 
/* Some stuff with my class BUT NEVER CALL TO myClassX.getAlpha() */

The above code compiles with MSVC but not with GCC, saying (of course):

MyClass.h:109:39: error: m_alpha was not declared in this scope

So my questions are: What does the standard say about this? Is that an optimization from MSVC and if so, what is optimized in this case?

I assume MSVC does not generate the code of getAlpha because it's never called, but as always with MSVC I think it is not a standard behaviour.

Was it helpful?

Solution

As far as I know MSVC is not always compliant and, as an extension, allows specialization of member functions inside a class.

MSVC is not generating the code when not explicitly told to. If you use that function member it will trigger the error, also if you explicitly specialize it or explicitly instantiate it:

template <typename T>
class MyClass {
public:
  int getAlpha () { return m_alpha32 ; }
private:
  int m_alpha1 ; // See the "1" here
};

template<> class MyClass<int>{ // Explicit specialization triggers the error
public: 
  int getAlpha () { return m_alpha32 ; }
private:
  int m_alpha1 ; // See the "1" here
};

template class MyClass<int>; // Explicit instantiation, triggers the error

int main(){

  MyClass<int> obj; // doesn't trigger the error alone

  obj.getAlpha(); // trigger the error


  return 0;
}

Also take a look here: http://msdn.microsoft.com/en-us/library/7y5ca42y(v=vs.110).aspx

The compiler generates code for a template class or function when the class or function is instantiated. A member function is instantiated when it is called, and a virtual member function is instantiated when its class is constructed. This can cause problems if you are building a library with templates for other users.

and also

A class template is first specialized and then instantiated by the compiler.

Thus either no diagnostic is being required or code isn't being generated at all.

OTHER TIPS

There is no valid specialization of the template. The code is thus ill formed, but no diagnostic is needed as there is no tentative to specialize it. So both compilers are conforming on this point.

For the references lovers, 14.6/7 in C++-98 and 14.6/8 in C++11 both contains:

No diagnostic shall be issued for a template definition for which a valid specialization can be generated. If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required.

Here there is no T for which it is possible to generate code for MyClass<T>::getAlpha (in standardese, there is no valid specialization for that template), it is an error (in standardese, the code is ill-formed) but the compiler doesn't have to detect it (in standardese, no diagnostic is required).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top