基类模板的成员超出具有相同模板参数的派生类模板的范围

编程入门 行业动态 更新时间:2024-10-14 20:19:24
本文介绍了基类模板的成员超出具有相同模板参数的派生类模板的范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

以下代码为我提供了编译错误'value'未在此范围内声明

The following code gives me a compilation error 'value' was not declared in this scope.

template<class T> struct Base { int value; }; template <class T> struct Derived : public Base<T> { int getValue() { return value; } };

我觉得非常奇怪,

  • 如果派生继承自 Base< std :: string> / li>
  • 如果我返回Base< T> :: value ,则代码将编译。
  • if Derived inherits from Base<std::string>, the code compiles,
  • if I return Base<T>::value, the code compiles.

为什么代码不编译?在 Derived< T> :: getValue()?

Why doesn't the code compile as it is? In what way is 'value' not declared in the scope of Derived<T>::getValue()?

推荐答案

因为 value 是一个非限定名称,在名称查找的第一阶段,没有提示这是从基类继承的数据成员(它尚未实例化 Base< T> )。因此,它将搜索全局命名空间,并找不到名为 value 的变量;

Because value is an unqualified name, and during the first phase of name lookup, the compiler will have no clue that this is a data member inherited from a base class (it hasn't instantiated Base<T> yet). Thus, it will search the global namespace, and find no variable called value; consequently, it will emit an error.

这是一个典型的方法来解决这个问题:

Here is a typical approach to solve this problem:

template <class T> struct Derived : public Base<T> { int getValue() { return this->value; } // ^^^^^^ };

显式解引用这个告诉编译器下面的名称是(可能是继承的)数据成员的名称,并且查找应该被延迟到成员函数实际被实例化的点。当然,你的解决方案是:

Explictly dereferencing this tells the compiler that the name that follows is the name of a (possibly inherited) data member, and the lookup should be delayed to the point where the member function is actually instantiated. Of course, your solution of doing:

return Base<T>::value;

同样好,因为它也告诉编译器 value 从基类 Base 继承。

Is equally good, because it also tells the compiler that value is inherited from the base class Base<T>.

对于从 Base< std :: string> 派生的关注,编译器可以立即查找是否 Base< std :: string> 包含名为 value 的数据成员(因为它不依赖于任何模板参数)

For what concerns deriving from Base<std::string>, the compiler can immediately go and look up whether Base<std::string> contains a data member named value (because it does not depend on any template parameter) and if that is the case, it will be able to determine that the expression is well-formed.

但是,如果你的基类是 Base< ; T> ,其中 T 在名称查找的第一阶段未知,编译器不能告诉什么 是 Base 对于不同的 T 的专业化甚至可能没有 value )。

However, if your base class is Base<T>, where T is unknown during the first phase of name lookup, the compiler can't tell what value is (specializations of Base for different Ts may even not have value at all).

C ++ 11标准的第14.6 / 3段:

Paragraph 14.6/3 of the C++11 Standard:

类或类模板的定义,如果基类依赖于模板参数,则在类模板的定义点处的非限定名称查找期间不检查基类 scope,成员或在类模板或成员的实例化期间。 [...] [示例: struct A { struct B { / ... / }; int a; int Y; }; int a; template<class T> struct Y : T { struct B { / ... / }; B b; // The B defined in Y void f(int i) { a = i; } // ::a Y* p; // Y<T> }; Y<A> ya;

成员 A :: B code> A :: a 和 A :: Y 模板参数 A 不影响 Y< A> 中的名称的绑定。 - end example ]

The members A::B, A::a, and A::Y of the template argument A do not affect the binding of names in Y<A>. —end example ]

更多推荐

基类模板的成员超出具有相同模板参数的派生类模板的范围

本文发布于:2023-08-04 09:19:19,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1295044.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模板   成员   参数   派生类

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!