为什么编译器试图实例化一个我实际上没有在任何地方实例化的模板?

时间:2011-06-07 10:40:45

标签: c++ visual-studio-2010 templates c++11 instantiation

在下方更新
以下是我在main.cpp中的完整代码:

template<class T>
struct other_traits;

template<class T>
struct some_traits{
    typedef decltype(&T::operator()) Fty;
    typedef typename other_traits<Fty>::type type;
};

int main(){
}

但在g++ compiles just fine

时,我在Visual Studio 2010中遇到以下错误
  

src \ main.cpp(9):错误C2146:语法错误:缺少';'在标识符'type'之前   --src \ main.cpp(10):参见正在编译的类模板实例化“some_traits<T>”的引用   src \ main.cpp(9):错误C2868:'some_traits<T>::type':using声明的非法语法;预期的合格名称

(我喜欢最后一个,总重量。)

我可以将其视为VC10中的错误,还是有充分的理由进行早期实例化?或者是decltype的错误使编译器认为Fty不是依赖名称?


更新:我试图欺骗编译器,认为Fty是使用基类继承的依赖名称:

template<class T>
struct other_traits;

template<class R, class C>
struct other_traits<R (C::*)()>{
    typedef R type;
};

template<class Fty>
struct base_traits{
    typedef typename other_traits<Fty>::type type;
};

template<class T>
struct some_traits
    : public base_traits<decltype(&T::operator())>
{};

但是编译器仍然试图在现场实例化/编译所有内容,引发这些错误:

src\main.cpp(13): error C2039: 'type' : is not a member of 'other_traits<T>'
          with
          [
              T=
          ]
          src\main.cpp(19) : see reference to class template instantiation 'base_traits<Fty>' being compiled
          with
          [
              Fty=
          ]
          src\main.cpp(19) : see reference to class template instantiation 'some_traits<T>' being compiled
src\main.cpp(13): error C2146: syntax error : missing ';' before identifier 'type'
src\main.cpp(13): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
src\main.cpp(13): error C2602: 'base_traits<Fty>::type' is not a member of a base class of 'base_traits<Fty>'
          with
          [
              Fty=
          ]
          src\main.cpp(13) : see declaration of 'base_traits<Fty>::type'
          with
          [
              Fty=
          ]
src\main.cpp(13): error C2868: 'base_traits<Fty>::type' : illegal syntax for using-declaration; expected qualified-name
          with
          [
              Fty=
          ]

请注意,模板参数为空。有什么想法吗?

4 个答案:

答案 0 :(得分:2)

似乎是 Bug (如果没有设置如下所述的特殊标志)。 以下是Oracle website对C ++模板的摘录:

  

7.2.2

     

ISO C ++标准允许   开发人员编写模板类   所有成员可能不是   具有给定模板的合法   论点。 只要违法   成员没有实例化,   计划仍然很好。 ISO   C ++标准库使用它   技术。然而    -template = wholeclass 选项实例化所有成员,因此   不能与这样的模板一起使用   用实例化的类   有问题的模板参数。

答案 1 :(得分:1)

我认为当编译器看到decltype

时,你偶然发现了与过早实例化相关的错误

答案 2 :(得分:0)

template<class T>
struct other_traits; // <-- I don't see a "type" attribute in this struct

template<class T>
struct some_traits{
    typedef decltype(&T::operator()) Fty;
    typedef typename other_traits<Fty>::type type; // <-- Here you are trying to access other_traits<T>::type which doesn't exist
};

int main(){
}

答案 3 :(得分:0)

你在这里做了一个假设,这在技术上是不正确的。让我们先解决这个问题。

您认为语法错误意味着实例化了模板。这不是模块应该编译的方式。在实例化之前首先编译模板。这是查找非依赖名称的阶段。在这个阶段当然可以找到语法错​​误。例如,无论模板参数如何,任何必须声明的内容都必须以;结尾。

现在正确的问题是编译器在考虑other_traits<T>的特化时是否正确。第9行当然没有这样的专业化,即使以后可能有专业化。但是那些实例化的相关点是什么?我必须要查看(对不起,AFS远离Standardother_traits&lt; T&gt;将是第9行,然后 没有特化,other_traits<Fty>::type无效。如果实例化的话for other_traits<Fty>::typesome_traits<T>的实例化点相同,即无,然后{1}}应在第1阶段接受。