1

最初にMicrosoft VS(2008年だと思います)で構築されたDebian 6.0.6(gcc 4.4.5を使用)で大規模なプロジェクトを構築しています。

問題と思われるのは、メンバーを として宣言し、 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 *ご協力いただければ幸いです。ありがとう!

4

1 に答える 1

0

これは とはまったく関係ありませんtypename

標準ではstd::set<T>::iteratorstd::set<T>::const_iteratorを同じ型にすることができ、GCC では型は同じです。

その理由は、std::setたとえば byの要素を変更する*iter = valと、セット要素の順序が無効になり、セットの要素が常に順序どおりであるという不変条件が破られる可能性があるためです。型をiterator変更可能なイテレータではなく定数イテレータにすることで、要素を変更することができなくなり、セットの順序が崩れるのを防ぐことができます。

したがって、GCC の実装では、イテレータを逆参照するときに を*iter取得し、const entitType&そのアドレスを&*iter取得するときに を取得します。const entityType*

于 2012-10-02T23:02:28.333 に答える