我正在尝试实现优先级队列。这是接口类的代码:
template<typename TYPE, typename COMP_FUNCTOR = std::less<TYPE>>
class priority_queue {
public:
typedef unsigned size_type;
virtual ~priority_queue() {} // impleted but does nothing, this is not a pure virtual function
virtual void fix() = 0;
/* some other methods*/
protected:
COMP_FUNCTOR compare;
};
导致问题的代码:
template<typename TYPE, typename COMP_FUNCTOR = std::less<TYPE>>
class sorted_priority_queue : public priority_queue<TYPE, COMP_FUNCTOR> {
public:
typedef unsigned size_type;
template<typename InputIterator>
sorted_priority_queue(InputIterator start, InputIterator end, COMP_FUNCTOR comp = COMP_FUNCTOR());
/* some other methods*/
private:
std::vector<TYPE> data;
};
template<typename TYPE, typename COMP_FUNCTOR>
template<typename InputIterator>
sorted_priority_queue<TYPE, COMP_FUNCTOR>::sorted_priority_queue(
InputIterator start, InputIterator end, COMP_FUNCTOR comp) {
for(auto it = start; it != end; ++it) {
data.push_back(*it);
}
fix();
this->compare = comp; // <--- the line that causes problem
}
当我尝试在最后一行做compare = comp时,它说“使用未声明的标识符'比较'”,我必须声明这个 - &gt;为了访问compare,这是在接口类中定义的受保护成员变量,为什么?谢谢。
答案 0 :(得分:2)
这与在C ++模板类中执行名称查找的方式有关。实际的机制有点棘手,但实际上,当编译器第一次看到模板类时,它会尝试在不使用模板参数的情况下解析它可以使用的所有名称。在这种情况下,这意味着当它看到名称compare
在没有this->
前缀的情况下使用时,编译器期望compare
引用可以在没有任何模板先验知识的情况下找到的内容参数。不幸的是,在您的情况下,编译器无法在不知道模板参数的情况下找出compare
引用的内容,因为compare
存储在基类中,这取决于模板参数。因此,在尝试找出compare
引用的内容时,它不会查看基类内部,因此会出错。
另一方面,如果显式编写this->compare
,编译器知道compare
是该类的成员,并将推迟查找它引用的名称,直到模板参数为止实际上是可用的。
这是用于实际出现此类错误的语言中为数不多的几种情况之一,如果您正在访问
,这是一个很好的经验法则然后您将需要使用this->
前缀来避免此问题。