I have been implementing a binary heap as a subclass of priority_queue, and run into a situation I cannot understand, despite considerable effort. Here is the working version of the code. (Background: c is priority_queue’s backing vector.)

#include <queue>
using namespace std;

template <class nodetype>
class BinaryHeap : public priority_queue<int> {
public:
    BinaryHeap() { vec = &c; }
    vector<nodetype> *vec;
};

int main() {
    BinaryHeap<int> b;
}

However, when you change the superclass to:

class BinaryHeap : public priority_queue<nodetype>

...the compiler complains about the usage of c :

h.cpp: In constructor ‘BinaryHeap<nodetype>::BinaryHeap()’:
h.cpp:10: error: ‘c’ was not declared in this scope

This seems all the more strange because:

  1. “[c] is equivalent to this->c” (ref)-如果您使用vec = &this->c,它确实可以编译。

  2. 如果再次向BinaryHeap添加using声明using priority_queue<nodetype>::c,则会对其进行编译。但是,该使用声明应该是不必要的。

  3. 编辑:

    因此,显然发生了这种情况,因为``编译器在查找非依赖名称时不查找依赖基类''(ref)–“c”不依赖于模板参数,因此也不依赖于,priority_queue<nodetype>确实依赖于模板参数– nodetype –因此是依赖的。

    另一方面,priority_queue<int>不依赖于nodetype,因此也不依赖于ojit_code,因此编译器在解析其他不依赖的名称时会在其中查找名称。

    它是否正确?如果是这样:

    当“在查找非依赖名称时在依赖基类中查找”时,该标准为何强制要求这种行为。有什么好处?编译时性能优化?

    最佳答案

    最后,这仅仅是定义模板行为的标准问题。 (C++ 11)标准对 [temp.nondep](14.6.3)中的非依赖名称解析进行了以下说明:



    由于c显然不依赖模板参数,因此编译器将其视为非依赖名称。因此,基本上会发生以下情况:当编译器查看BinaryHeap时,notetype的实际类型是未知的,因此priority_queue<nodetype>也是如此,因为它取决于nodetype(可能是部分特化)。因此,编译器无法考虑该类型的分辨率(因为我们在谈论的是模板定义的点,而不是实例化的点)。因此,它将在包含范围中查找名为c的内容,但找不到任何内容,因此拒绝了该代码。使用this->c(或using priority_queue<nodetype>::c)使c成为从属名称(由于它不是BinaryHeap的成员,因此它必须是priority_queue<nodetype>的成员),因此名称查找被延迟到模板的实例化点为止,在该点处notetype是已知的,并且编译器因此可以搜索priority_queue<nodetype>

    对于您的编辑:是的,这是正确的

    关于c++ - 模板化父类(super class)的 protected 成员应该在子类中可见,但(有时)不是,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8766576/

10-12 23:52