[英]Can a Specialized Template Class Inherit from Another Specialized Template Class?
I first defined我首先定义
class Hash
{
};
Then a specialization of Hash.然后是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;
};
I want to use this specialized version of Hash to implement another specialization: Hash of String-Valued Keys.我想使用这个特殊版本的 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);
};
But it seemed I cannot access fields in the class Hash.但似乎我无法访问类 Hash 中的字段。 Why?
为什么?
When you say "I cannot access fields in the class Hash" I guess you mean, that you when you are using Hash<string, T>
(for some type T
) that you cannot call the overloaded functions from Hash<int, T>
.当您说“我无法访问类 Hash 中的字段”时,我猜您的意思是,当您使用
Hash<string, T>
(对于某些类型T
)时,您无法从Hash<int, T>
调用重载函数. The reason for this is name hiding: when you overload a member function in a derived class, all members with the same name in the base class are hidden unless you make them explicitly available.这样做的原因是名称隐藏:当您在派生类中重载成员函数时,基类中所有具有相同名称的成员都将被隐藏,除非您明确使它们可用。 The way to do it is a
using
declaration:这样做的方法是
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);
};
If you just need to access the base class members from your derived class's implementation, you can also access the names using qualification with the class name.如果您只需要从派生类的实现中访问基类成员,您还可以使用带有类名的限定来访问名称。 For example:
例如:
template <typename T>
bool Hash<string, T>::insert(string key, T val) {
return this->Hash<int, T>::insert(this->str2key(key, val);
}
Thinking a bit more about the question, there is another potential issue: If you access the data members in the base class you need to make sure that the compiler considers the name a dependent name.进一步思考这个问题,还有另一个潜在问题:如果您访问基类中的数据成员,您需要确保编译器将该名称视为依赖名称。 Otherwise it is looked up in phase one and won't the names in the base because the can only be found in phase two:
否则,它会在第一阶段查找,而不会在基础中查找名称,因为只能在第二阶段找到:
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
}
Personally, I wouldn't publicly derive from a class with a different key but I assume you have your reasons.就个人而言,我不会公开从具有不同密钥的类派生,但我认为您有自己的理由。 BTW, I assume that your primary declaration of
Hash
looks something like this although it doesn't matter for the problem, really:顺便说一句,我假设您对
Hash
的主要声明看起来像这样,尽管这对问题无关紧要,实际上:
template <typename K, typename T>
class Hash;
(if it doesn't have any members, I would rather not define it, either). (如果它没有任何成员,我也宁愿不定义它)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.