我正在用C ++编写一段模板化的代码。它在VS 2005中运行得很好,但是当我尝试用g ++编译时,我得到了一些非常奇怪的错误。
必不可少的代码(简化为最小,不编译)如下:
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 :(得分:4)
在依赖的基类中不会查找非限定名称(您的基类依赖于模板参数Q
)。限定该名称,它将起作用。
typename Derived::ThisType q;
答案 1 :(得分:1)
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;
答案 2 :(得分:0)
您缺少 typename
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(){}
答案 3 :(得分:0)
代码确实是不正确的。当基类依赖于模板参数时,在查找非限定名称时不会通过名称查找来考虑它。
在您的情况下,不会在基类ThisType
中查找未限定名称Intermediate<Derived<Q> >
,因为您的基类取决于模板参数Q
。