C++ 从C+中的派生类构造函数中的基模板类访问变量+;

C++ 从C+中的派生类构造函数中的基模板类访问变量+;,c++,class,templates,inheritance,constructor,C++,Class,Templates,Inheritance,Constructor,让我们看看这个简单的代码示例,其中包括一个基类和一个从基类派生的类,它需要在其构造函数中包含基类成员的地址 #include <vector> #include <inttypes.h> #include <stdio.h> class Base { protected: std::vector<uint32_t> arr; public: Base(std::vector<uint32_t> arr_in): arr(arr

让我们看看这个简单的代码示例,其中包括一个基类和一个从基类派生的类,它需要在其构造函数中包含基类成员的地址

#include <vector>
#include <inttypes.h>
#include <stdio.h>

class Base
{
protected:
  std::vector<uint32_t> arr;
public:
  Base(std::vector<uint32_t> arr_in): arr(arr_in) {}
};

class Derived: public Base
{
private:
  uint32_t *parr;
public:
  Derived(std::vector<uint32_t> arr_in): Base(arr_in)
  {
    parr = &arr[0];
  }

  uint32_t *get_parr();
};

uint32_t *Derived::get_parr(void)
{
  return parr;
}

int main()
{
  std::vector<uint32_t> myarr(3, 1);
  Derived myderived(myarr);
  printf("myderived.myarr adress = %p", myderived.get_parr());
}
#包括
#包括
#包括
阶级基础
{
受保护的:
std::载体arr;
公众:
基(std::vector arr_-in):arr(arr_-in){
};
派生类:公共基
{
私人:
uint32_t*parr;
公众:
派生(标准::向量arr_-in):基(arr_-in)
{
parr=&arr[0];
}
uint32_t*get_parr();
};
uint32_t*派生::get_parr(void)
{
返回帕尔;
}
int main()
{
std::载体myarr(3,1);
衍生MyDerivated(myarr);
printf(“myderived.myarr地址=%p”,myderived.get_parr());
}
由于派生类的构造函数首先调用基类构造函数,然后才执行其代码块,因此已经可以访问基类的成员。所以一切正常

现在我更改代码示例,使我的两个类成为模板

#include <vector>
#include <inttypes.h>
#include <stdio.h>

template<typename T>
class Base
{
protected:
  std::vector<T> arr;
public:
  Base(std::vector<T> arr_in): arr(arr_in) {}
};

template<typename T>
class Derived: public Base<T>
{
private:
  T *parr;
public:
  Derived(std::vector<T> arr_in): Base<T>(arr_in)
  {
    parr = &arr[0];
  }

  T *get_parr();
};

template<typename T>
T *Derived<T>::get_parr(void)
{
  return parr;
}

int main()
{
  std::vector<uint32_t> myarr(3, 1);
  Derived<uint32_t> myderived(myarr);
  printf("myderived.myarr adress = %p", myderived.get_parr() );
}
#包括
#包括
#包括
模板
阶级基础
{
受保护的:
std::载体arr;
公众:
基(std::vector arr_-in):arr(arr_-in){
};
模板
派生类:公共基
{
私人:
T*parr;
公众:
派生(标准::向量arr_-in):基(arr_-in)
{
parr=&arr[0];
}
T*get_parr();
};
模板
T*派生::get_parr(void)
{
返回帕尔;
}
int main()
{
std::载体myarr(3,1);
衍生MyDerivated(myarr);
printf(“myderived.myarr地址=%p”,myderived.get_parr());
}
但第二个示例在编译时给出了以下错误消息:

class_temp.cpp: In constructor ‘Derived<T>::Derived(std::vector<T>)’:
class_temp.cpp:23:13: error: ‘arr’ was not declared in this scope
     parr = &arr[0];
class_temp.cpp:在构造函数“派生的::派生的(标准的::向量)”中:
class_temp.cpp:23:13:错误:“arr”未在此作用域中声明
parr=&arr[0];
那么,为什么在模板类的第二个示例中,派生类构造函数不知道基类成员? 还是我做错了什么


谢谢。

arr
现在是一个从属名称。它取决于
T
。如果有一些
T
专用于
Base
而没有
arr
,该怎么办?具体而言,从[临时部门]:

在类或类模板的定义中,不检查依赖基类(14.6.2.1)的范围 在类模板或成员的定义点或 类模板或成员的实例化

Base
是一个依赖的基类-它依赖于模板参数
T
,因此在非限定名称查找期间不会检查其范围。解决方法是使用限定名称查找。即,类名:

parr = &Base<T>::arr[0];

在第二种情况下,
Base
是一个模板,有人可能会为模板添加专门化,所有这些都带有不同的成员变量。编译器在看到
T
是什么之前无法知道


还可能有一个全局的
arr
可以适应。您可以使用
this->arr[0]
来帮助编译器指出它始终是一个成员变量。

我确信这是一个重复的变量,但由于某些原因,我找不到任何内容。为什么
parr=&Base::arr[0]有效吗?由于
派生的
是由
类派生的:公共基
继承的,如果对
有专门化,可能会使
arr
不存在,但为什么相同的逻辑不适用于
&Base::arr[0]
?@allankunzi,因为在非限定查找期间未查找依赖基类的范围-如果我们执行
base::arr
,则我们执行的是限定查找。如果
arr
不存在,那将是一个查找失败-但如果它确实存在,我们会找到它。
parr = &this->arr[0];