模板实例错误,MSVC与GCC

时间:2014-05-06 10:21:29

标签: c++ templates g++ visual-studio-2010

嗯,我得到了以下模板(包含一个很大的错误):

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
}

在我的代码中,我做了类似的事情:

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() */

上面的代码用MSVC编译,但不是用GCC编写,当然说:

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

所以我的问题是:标准对此有何看法?这是来自MSVC的优化,如果是,那么在这种情况下优化了什么?

我假设MSVC不生成getAlpha的代码,因为它从未被调用,但与MSVC一样,我认为它不是标准行为。

2 个答案:

答案 0 :(得分:1)

据我所知,MSVC并不总是兼容,并且作为扩展,允许在类中使用成员函数的专门化。

MSVC在未明确告知时未生成代码。如果您使用该函数成员,它将触发错误,如果您明确地专门化它或显式实例化它:

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;
}

另请看这里:http://msdn.microsoft.com/en-us/library/7y5ca42y(v=vs.110).aspx

  

编译器为模板类或函数生成代码   类或函数被实例化。成员函数被实例化   当它被调用时,虚拟成员函数被实例化时   它的类是构建的。如果您正在构建,这可能会导致问题   包含其他用户模板的库。

以及

  

类模板首先是专用的,然后由实例化实例化   编译器。

因此,要么不需要诊断,要么根本不生成代码。

答案 1 :(得分:-1)

模板没有有效的专业化。因此代码形成不良,但不需要诊断,因为没有专门的专业化。因此,两个编译器都在遵循这一点。

对于参考爱好者来说,C ++中的14.6 / 7 - 和C ++ 11中的14.6 / 8都包含:

  

对于有效专业化的模板定义,不应发出诊断   可以生成。如果无法为模板定义生成有效的专门化,   并且该模板未实例化,模板定义不正确,没有   需要诊断。

这里没有T可以为MyClass<T>::getAlpha生成代码(在标准中,该模板没有有效的专门化),这是一个错误(在标准中,代码是格式错误的但是编译器不必检测它(在标准中,不需要诊断)。