.cpp.模板类继承不起作用

cpp. Template class inheritance does not work

本文关键字:继承 不起作用 cpp      更新时间:2023-10-16

我有以下代码:

template <class T>
class Planet{
    protected:
        std::map<ID, std::shared_ptr<T>> population;
        ID freeId;
    public:
    //@todo dorobić name
        Planet();
        T& registerCitizen(std::string);
        T& findCitizen(ID);
        T& findCitizen(std::string);
};
template <class T>
class PairPlanet: public Planet<T>{
    public:
        T& registerCitizen(T&, T&);
};

这里的问题是,PairPlanet似乎不是从行星继承而来的:例如,如果我尝试定义:模板

T& PairPlanet<T>::registerCitizen(T& per1, T& per2){
    T* new_person = new T(per1.citizenName+"&"+per2.citizenName,freeId);
    population.insert(std::pair<ID, T>(freeId, *new_person)).first;
    freeId++;
    return *new_person; 
};

我收到一个信息,人口和freeId都是未定义的。我可以要求一些提示吗?

简短回答:您需要使用显式this->来引用freeIdpopulation

template <class T>
T& PairPlanet<T>::registerCitizen(T& per1, T& per2){
    T* new_person = new T(per1.citizenName+"&"+per2.citizenName,
                          this->freeId);
    // The original had a pointless `.first` at the end,
    // but I removed it because it was pointless.
    this->population.insert(std::make_pair(this->freeId, *new_person));
    ++this->freeId;
    return *new_person; 
};

原因是"非依赖名称查找"(当前C++14草案的§14.6.3 [temp.nondep]):

模板定义中使用的非依赖名称是使用常用名称查找找到的,并在使用它们时绑定。

非依赖名称是不明显依赖于模板参数的名称。freeIdpopulation的无条件使用并不明显依赖于任何东西,因此"使用通常的名称查找......在使用它们时"。换句话说,编译器在定义PairPlanet模板期间,在它们出现在程序文本中的点解析它们。它们不在类本身中,也不在全局范围内,因此它找不到它们并抱怨。

您的意图是freeIdpopulation来自基类,基类依赖于模板参数。因此,您需要通过显示它们是 this 指向的对象的成员来明确声明这些标识符是依赖的。对于依赖名称,编译器使用标准下一部分的名称查找策略,该策略将名称查找推迟到模板参数已知时的实例化点。此时,编译器已经确定了基类的定义,并且其中定义的名称可用于查找。