我有以下代码:
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都未定义。我可以要一些提示吗?
答案 0 :(得分:0)
简短回答:您需要使用明确的this->
来引用freeId
和population
:
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]):
模板定义中使用的非依赖名称是使用通常的名称查找找到的,并在使用它们时绑定。
非依赖名称是不明显依赖于模板参数的名称。 freeId
和population
的无限制使用并不明显地依赖于任何东西,所以在“使用它们时使用通常的名称查找”查找它们。换句话说,编译器在定义PairPlanet
模板期间将它们解析为它们出现在程序文本中的位置。他们不属于班级本身,也不属于全球范围,所以它找不到并抱怨。
您的意图是freeId
和population
来自基类,它取决于模板参数。因此,您需要通过显示它们是this
指向的对象的成员来明确声明这些标识符是相关的。对于从属名称,编译器使用标准的下一部分中的名称查找策略,该策略将名称查找推迟到模板参数已知时的实例化点。此时,编译器已经计算出基类的定义,并且在其中定义的名称可用于查找。