gpt4 book ai didi

c++ - 基类模板的成员在具有相同模板参数的派生类模板中超出范围

转载 作者:IT老高 更新时间:2023-10-28 22:27:00 26 4
gpt4 key购买 nike

下面的代码给了我一个编译错误'value'没有在这个范围内声明

template<class T>
struct Base {
int value;
};

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

我觉得很奇怪

  • 如果 Derived继承自 Base<std::string> ,代码编译,
  • 如果我 return Base<T>::value , 代码编译。

为什么代码不能按原样编译? Derived<T>::getValue() 的范围内没有以何种方式声明“值(value)”? ?

最佳答案

因为value是一个非限定名称,在名称查找的第一阶段,编译器不会知道这是一个从基类继承的数据成员(它还没有实例化Base<T>)。因此,它将搜索全局命名空间,并没有找到名为 value 的变量。 ;因此,它会发出错误。

这是解决此问题的典型方法:

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

显式取消引用 this告诉编译器后面的名字是一个(可能继承的)数据成员的名字,并且查找应该延迟到成员函数被实际实例化的地方。当然,您的解决方案是:

return Base<T>::value;

同样好,因为它还告诉编译器 value继承自基类 Base<T> .

关于源自 Base<std::string> 的问题,编译器可以立即去查找是否Base<std::string>包含一个名为 value 的数据成员(因为它不依赖于任何模板参数)如果是这种情况,它将能够确定表达式是格式正确的。

但是,如果您的基类是 Base<T> , 其中 T在名称查找的第一阶段是未知的,编译器无法判断 value是(Base 的特化为不同的 T s 甚至可能根本没有 value)。

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

In the definition of a class or class template, if a base class depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member. [...] [Example:

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;

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 ]

关于c++ - 基类模板的成员在具有相同模板参数的派生类模板中超出范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15813863/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com