我正在使用Debian 6.0.6(使用gcc 4.4.5)构建一个大型项目,该项目最初是在Microsoft VS(2008,我认为)中构建的。
什么似乎是问题是当我宣布一个成员为
typedef typename std::set<T>::iterator iterator
,然后使用这个迭代器,gcc似乎把它解释为(const T *)。
包含typename
名称的类的部分:
template <class entityType>
class entityArray
{
private: std::set<entityType> m_array;
public: typedef typename std::set<entityType>::iterator iterator;
...
public:
entityType* At( const char* name);
...
};
以及讨论所需的其他几个类:
class entity
{
private:
entity* m_parent;
int m_ncid;
std::string m_name;
public:
entity () { m_ncid = 0; m_parent = NULL;}
virtual ~entity () {};
...
};
class attribute : public entity
{
public:
attribute(){};
virtual ~attribute(){};
};
class var : public entity
{
private:
entityArray<attribute> m_atts;
public:
var(){}
virtual ~var(){}
...
};
class dim : public entity
{
public:
dim() {};
virtual ~dim() {};
};
class group : public entity
{
private:
entityArray<var> m_vars;
entityArray<dim> m_dims;
...
public:
dim* DimAt( const char* dimname ) { return m_dims.At(dimname);}
};
现在通过调用函数iterator
来初始化DimAt
,而函数At
又调用At
。第一个类中的template <class entityType>
entityType* entityArray<entityType>::At( const char* name )
{
entityType dummy;
iterator iter;
entityType* ptr;
... define dummy ...
iter = m_array.find( dummy );
ptr = (iter != m_array.end()) ? &(*iter) : NULL;
return ptr;
}
函数定义为:
error: invalid conversion from const dim* to dim*.
编译以上产品
&(*iter)
,指的是typename
。
我意识到iterator
是声明const *
所必需的,因为该类型是一个依赖和限定名称,但我不明白为什么这个替换({{1}})正由编译器执行。我很感激您提供的任何帮助。谢谢!
答案 0 :(得分:0)
这与typename
完全无关。
该标准允许std::set<T>::iterator
和std::set<T>::const_iterator
属于同一类型,而GCC的类型相同。
原因是修改std::set
的元素,例如by *iter = val
可能会使set元素的顺序无效,从而破坏了set的元素始终有序的不变量。通过使iterator
类型成为常量迭代器而不是可变迭代器,不可能改变元素,从而防止破坏集合的顺序。
因此,使用GCC的实现,当您使用*iter
取消引用迭代器时,您会获得const entitType&
,当您使用&*iter
获取其地址时,您会获得const entityType*