C++模板的一个语法问题……纠结中……
[it](事实上,原帖在CSDN(http://topic.)上, 但是太心急这个问题了,所以在两个地方发了贴……大家不要BS我啦……)[/it]是这样的,我想写个“图”类,实现图的基本操作。因为“边”和“顶点”的主要操作都是查找。我准备通过从STL继承相应的类来完成基本的操作,在VC下把这个程序写完了,可是试验GCC的时候出了问题。下面贴主要的问题示例代码:
/*****************************************************************
** HighlightCodeV3.0 software by yzfy(雨中飞燕) http:// **
*****************************************************************/
#include <set>
#include <iostream>
using namespace std;
template<class TData>
class CSet : set<TData>
{
public:
using set<TData>::end;
using set<TData>::iterator;
bool Find(const TData& data)
{
iterator it=find(data);
return it != end();
}
};
int main()
{
CSet<char> s;
s.Find(10);
}
** HighlightCodeV3.0 software by yzfy(雨中飞燕) http:// **
*****************************************************************/
#include <set>
#include <iostream>
using namespace std;
template<class TData>
class CSet : set<TData>
{
public:
using set<TData>::end;
using set<TData>::iterator;
bool Find(const TData& data)
{
iterator it=find(data);
return it != end();
}
};
int main()
{
CSet<char> s;
s.Find(10);
}
大家可以试试看,这段代码在VC下编译通过,但是在GCC下提示找不到“iterator”。我就奇怪了。我都已经显式的using了,难道还不行么?(事实上,如果不using,会出另外一个error,好像说是在it前丢失了模板参数……)。
OK,我忍了,写了下面的代码:
bool Find(const TData& data)
{
set<TData>::iterator it=find(data);
return it != end();
}
{
set<TData>::iterator it=find(data);
return it != end();
}
还是一模一样的问题,OK,接下来:
template<typename T>
bool Find(const T& data)
{
set<T>::iterator it=find(data);
return it != end();
}
bool Find(const T& data)
{
set<T>::iterator it=find(data);
return it != end();
}
抓狂,编译器仍然跟我装找不到iterator的定义!!!无奈跑去翻标准,看到下面一段:(摘自ISO C++03,14.6.2)
3 In the definition of a class template or a member of a class template, if a base class of the class template depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.
[Example:
typedef double A;
template <class T> class B {
typedef int A;
};
template <class T> struct X : B <T> {
A a; // a has type double
};
The type name A in the definition of X <T> binds to the typedef name defined in the global namespace scope, not to the typedef name defined in the base class B <T>. ]
[Example:
struct A {
struct B { /* ... */ };
int a;
int Y;
};
int a;
template <class T> struct Y : T {
struct B { /* ... */ };
B b; // The B defined in Y
void f(int i) { a = i; } // ::a
Y* p; // Y <T>
};
Y <A> ya;
The members A::B, A::a, and A::Y of the template argument A do not affect the binding of names in Y <A>. ]
于是郁闷了。说如果类的基类是由模板确定的,那么名称寻找就不会涉及到基类里面去……晕,那要怎么使用set里面的类型呢????好郁闷!(注意,set里面的函数仍然是可以使用的,比如find。矛盾ing……)。
好了,标准说是对“无限制”的名称的寻找,那么我写了set <T>::iterator为什么还是不行?非要我写set <char>::iterator才编译通过。这样的话还要模板有什么用嘛!!!而且VC里面,map是通过_Tree实现的,一开始就 typedef了Tree里面一大堆东西,如果这都不通过的话那么连STL库都没办法编译通过了!!(附:GCC的STL卑鄙地在类里面设置了一个树的成员对象,而没有使用继承……)
我只想继承实现,不想在类里面放个set的对象。各位高手,对于这个问题有没有什么解决方案?
[[it] 本帖最后由 StarWing83 于 2008-6-21 04:56 编辑 [/it]]