由于“;这个“;关键字在c++中通常是不必要的并且被省略了,为什么在这个例子中它是必需的

Since the "this" keyword is usually unnecessary and omitted in c++, why in this example it is required?

本文关键字:为什么 c++ 关键字 这个 不必要 由于      更新时间:2023-10-16

我正在尝试实现一个优先级队列。这是接口类的代码:

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时,它说"使用未声明的标识符'compare'",我必须声明这个->才能访问compare,compare是接口类中定义的受保护成员变量,为什么?非常感谢。

这与如何在C++模板类中执行名称查找有关。实际的机制有点棘手,但本质上,当编译器第一次看到模板类时,它会尝试在不使用模板参数的情况下解析所有名称。在这种情况下,这意味着当它看到名称compare在没有this->前缀的情况下使用时,编译器希望compare指的是在没有任何模板参数先验知识的情况下可以找到的东西。不幸的是,在您的情况下,编译器在不知道模板参数的情况下无法弄清楚compare指的是什么,因为compare存储在基类中,这取决于模板参数。因此,当试图弄清楚compare指的是什么时,它不会查看基类内部,因此会出现错误。

另一方面,如果显式编写this->compare,编译器就会知道compare是类的成员,并且会推迟查找它所指的名称,直到模板参数实际可用为止。

这是该语言中少数出现这种错误的情况之一,根据经验,如果您正在访问

  1. 基类中的某个东西
  2. 在模板类中
  3. 从依赖于模板参数的东西继承

那么您将需要使用this->前缀来避免这个问题。