2

最初に定義した

class Hash
{

};

次に、ハッシュの特殊化。

template <class T>
class Hash<int, T>
{
public:
    Hash(int slotN = 11);

    bool insert(int key, T val);
    bool remove(int key);
    bool contains(int key);
    bool query(int key, T& val) ;

protected:
    // Basic Variables of the Hash Model.
    list<int>* slot;
    list<T>* slotVal;
    int slotN;
};

この特殊化されたバージョンの Hash を使用して、別の特殊化を実装したいと思います: 文字列値キーのハッシュ。

template <class T>
class Hash<string, T> : public Hash<int, T>
{
public:
    Hash(int slotN);

    bool insert(string key, T val);
    bool remove(string key);
    bool contains(string key);
    bool query(string key, T& val) ;

private:

    // Calculate the String's Hash Key.
    int str2key( string key);
};

しかし、クラス Hash のフィールドにアクセスできないようです。なんで?

4

1 に答える 1

2

「クラス Hash のフィールドにアクセスできません」と言うとき、Hash<string, T>(何らかの type に対してT) を使用しているときに、 からオーバーロードされた関数を呼び出せないことを意味していると思いますHash<int, T>。この理由は、名前の隠蔽にあります。派生クラスでメンバー関数をオーバーロードすると、明示的に使用可能にしない限り、基底クラスで同じ名前を持つすべてのメンバーが非表示になります。それを行う方法はusing宣言です:

template <class T>
class Hash<string, T> : public Hash<int, T>
{
public:
    Hash(int slotN);

    using Hash<int, T>::insert;
    using Hash<int, T>::remove;
    using Hash<int, T>::contains;
    using Hash<int, T>::query;

    bool insert(string key, T val);
    bool remove(string key);
    bool contains(string key);
    bool query(string key, T& val) ;

private:

    // Calculate the String's Hash Key.
    int str2key( string key);
};

派生クラスの実装から基本クラスのメンバーにアクセスする必要がある場合は、クラス名で修飾を使用して名前にアクセスすることもできます。例えば:

template <typename T>
bool Hash<string, T>::insert(string key, T val) {
    return this->Hash<int, T>::insert(this->str2key(key, val);
}

質問についてもう少し考えてみると、別の潜在的な問題があります。基本クラスのデータ メンバーにアクセスする場合は、コンパイラがその名前を依存名と見なすようにする必要があります。それ以外の場合は、フェーズ 1 で検索され、フェーズ 2 でしか見つからないため、ベースの名前は検索されません。

template <typename T>
bool Hash<string, T>::insert(string key, T val) {
    int n0 = slotN; // doesn't work: looked up in phase 1
    int n1 = this->slotN; // OK: name is dependent
    int n2 = Hash<int, T>::slotN; // OK, too
}

個人的には、別のキーを持つクラスから公に派生することはありませんが、理由があると思います。ところで、Hash問題には関係ありませんが、主な宣言は次のようになっていると思います。

template <typename K, typename T>
class Hash;

(メンバーがいない場合は、どちらか定義したくありません)。

于 2012-11-17T16:03:36.800 に答える