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:
“[c] is equivalent to this->c” (ref)-如果您使用vec = &this->c
,它确实可以编译。
using priority_queue<nodetype>::c
,则会对其进行编译。但是,该使用声明应该是不必要的。 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/