Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用模板访问C++中的超类受保护成员 为什么C++编译器不能识别G和B是超级类的继承成员,如本代码所见: template<typename T> struct Superclass { protected: int b; void g() {} }; template<typename T> struct Subclass : public Superclass<T> { void f() { g(); // compiler error: uncategorized b = 3; // compiler error: unrecognized } };_C++_Templates_Inheritance - Fatal编程技术网

用模板访问C++中的超类受保护成员 为什么C++编译器不能识别G和B是超级类的继承成员,如本代码所见: template<typename T> struct Superclass { protected: int b; void g() {} }; template<typename T> struct Subclass : public Superclass<T> { void f() { g(); // compiler error: uncategorized b = 3; // compiler error: unrecognized } };

用模板访问C++中的超类受保护成员 为什么C++编译器不能识别G和B是超级类的继承成员,如本代码所见: template<typename T> struct Superclass { protected: int b; void g() {} }; template<typename T> struct Subclass : public Superclass<T> { void f() { g(); // compiler error: uncategorized b = 3; // compiler error: unrecognized } };,c++,templates,inheritance,C++,Templates,Inheritance,若我简化子类并从子类继承,那个么它就会编译。当g完全限定为超类::g和超类::b时,它也会编译。我正在使用LLVMGCC4.2 注意:如果我在超类中公开g和b,它仍然会失败,并出现相同的错误。这可以通过使用以下命令将名称拉入当前范围进行修改: 或者,正如您已经注意到的,通过限定全名 这是必要的,因为C++不考虑超类模板来进行名称解析,因为它们是依赖名称和不依赖名称。当您使用超类时,它会起作用,因为它不是模板,而是模板的实例化,因此它的嵌套名称不是依赖名称。Konrad的回答没有询问或回答所有这些

若我简化子类并从子类继承,那个么它就会编译。当g完全限定为超类::g和超类::b时,它也会编译。我正在使用LLVMGCC4.2


注意:如果我在超类中公开g和b,它仍然会失败,并出现相同的错误。

这可以通过使用以下命令将名称拉入当前范围进行修改:

或者,正如您已经注意到的,通过限定全名


这是必要的,因为C++不考虑超类模板来进行名称解析,因为它们是依赖名称和不依赖名称。当您使用超类时,它会起作用,因为它不是模板,而是模板的实例化,因此它的嵌套名称不是依赖名称。

Konrad的回答没有询问或回答所有这些的最终原因。不只是C++委员会随意说嘿,放弃依赖性的名字,没有人喜欢他们。相反,编译器甚至在模板被实例化之前就对其进行了一些检查,在知道t之前,它无法理解g或b,因为它通常无法在基类的可能专门化之间进行选择,例如,超类可能有int b,而超类有void b,而超类根本没有b。更显式的表单只是说信任我-这必须在实例化时来自基类,否则会出现编译器错误。

Microsoft的编译器无法遵守此规则。我是angry@Armen:只有这一条规则?哇,真的好多了-D这个指针解决方案在Mac 10.7上的stock g++上运行正常。请注意,如果模板参数过多,您也可以使用Subclass::Superclass::进行限定。我有点喜欢Microsoft不遵守这一规则。我真的希望有一个选项来延迟模板的所有符号检查,直到实例化。它将显著提高模板的表达能力,并减少许多语法噪音。这有点道理,但它肯定是模板的一个更模糊的功能。@ChrisWue:在这场竞赛中,它有很多竞争对手-GCC在过去的90年代能够处理这个问题,但是后来随着C++的发展,它被改变了。我假设它的处理方式在某些情况下会导致问题,这就是它被更改的原因。这是因为并非所有编译器默认使用的两阶段名称查找。这个问题有4种解决方案:1使用前缀Superclass::b和Superclass::g,2使用前缀this->a和this->g,3使用Superclass::a和Superclass::g添加语句,4使用启用许可模式的全局编译器开关。中介绍了这些解决方案的优缺点
template<typename T> struct Subclass : public Superclass<T> {
  using Superclass<T>::b;
  using Superclass<T>::g;

  void f() {
    g();
    b = 3;
  }
};
template<typename T> struct Subclass : public Superclass<T> {
  void f() {
    this->g();
    this->b = 3;
  }
};