2011-03-16 57 views
0

我在C++中编写了一个模板化很强的代码。它在VS 2005中完美运行,但是当我尝试在g ++中编译它时,出现了一些非常奇怪的错误。g ++模板bug或VC太自由了?

的代码的基本块(简化到最少,不编译要么)如下:

template <class Actual> 
class Generic 
{ 
public: 
    typedef Actual ThisType; 
}; 

template <class Actual> 
class Intermediate : public Generic<Actual> 
{ 
}; 

template <class Q> 
class Derived : public Intermediate<Derived<Q> > 
{ 
public: 
    void FooBar() 
    { 
     ThisType q; 
    } 
}; 

错误是: 在“‘ThisType’未在此范围内声明” 'q'正在被宣布的行。

奇怪的是,当Derived不是模板而是普通类时,一切正常。为什么编译器甚至在实例化之前会查看模板函数实现?我知道VC++在编译模板时检查得太少(未使用的模板甚至可能包含语法错误的代码) - 但是g ++在这里检查的太多了吗?我尝试添加一个没有希望的typename关键字,它也失败了。有没有什么办法让ThisType按预期工作?我害怕将它手动添加到每个派生类的想法 - 这是繁琐,冗余,不雅和错误诱导。

最好的问候, MZ

+0

我觉得有趣的是,'return * this;'不会引发任何编译错误,因为函数是void。 – karlphillip 2011-03-16 23:10:02

+4

如果你问这个问题,答案几乎总是“VC太自由了”。 – EboMike 2011-03-16 23:11:35

+1

我承认,当我看着这段代码时,我的大脑也得到了解析错误 – hirschhornsalz 2011-03-16 23:16:26

回答

1

信托Comeau online compiler

Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2 
Copyright 1988-2008 Comeau Computing. All rights reserved. 
MODE:strict errors C++ C++0x_extensions 

"ComeauTest.c", line 19: error: identifier "ThisType" is undefined 
      ThisType q; 
     ^

"ComeauTest.c", line 19: error: expected a ";" (perhaps on the previous statement) 
      ThisType q; 
       ^

2 errors detected in the compilation of "ComeauTest.c". 
从继承类

依赖类型名称没有考虑到,你可以尝试明确要求ThisType:

typename Intermediate<Derived<Q> >::ThisType q; 
+0

最后的错误很明显 - 我简化了代码,'return'在这个过程中幸存下来。尽管如此,它并没有多大帮助。代码不会编译。有什么解决方法吗? – MichalZ 2011-03-16 23:14:28

0

你缺少一个类型名

template <class Actual> class Generic { public: 
    typedef Actual ThisType; }; 

template <class Actual> class Intermediate : public Generic<Actual> { }; 

template <class Q> class Derived : public Intermediate<Derived<Q> > { public: 
    void FooBar() 
    { 
     typename Derived::ThisType q; 
     return *this; 
    } }; 

int main(){} 
+1

不编译。 – 2011-03-16 23:13:59

+0

'return * this; '??? – curiousguy 2011-10-28 17:30:40

4

不合格名称不在相关的基类中查找(您的基类取决于模板参数Q)。限定该名称,它会起作用。

typename Derived::ThisType q; 
+0

+1:是的,是的,这就是规则应该如何发声:) – 2011-03-16 23:17:53

+0

我不想限定 - 我宁愿在派生类中重新定义ThisType ...而且它对于VC来说非常简单。 – MichalZ 2011-03-16 23:21:11

+0

@MichalZ对于GCC也很简单。我在类派生类中找不到原因'typedef typename Intermediate > :: ThisType ThisType;应该不起作用。 – 2011-03-16 23:36:06

0

该代码确实是格式不正确。当基类取决于模板参数时,在查找不合格名称时,不会通过名称查找来考虑。

对于您的情况,由于您的基类取决于模板参数Q,所以不会在基类Intermediate<Derived<Q> >中查找不合格名称ThisType