Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.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++_Inheritance_Templates - Fatal编程技术网

C++ 从模板化父类访问继承的变量

C++ 从模板化父类访问继承的变量,c++,inheritance,templates,C++,Inheritance,Templates,考虑以下代码: template<class T> class Foo { public: Foo() { a = 1; } protected: int a; }; template<class T> class Bar : public Foo<T> { public: Bar() { b = 4; }; int Perna(int u); protected: int b; }; template<class T&g

考虑以下代码:

template<class T> class Foo
{
public:
  Foo() { a = 1; }

protected:
  int a;
};

template<class T> class Bar : public Foo<T>
{
public:
  Bar() { b = 4; };

  int Perna(int u);

protected:
  int b;

};

template<class T> int Bar<T>::Perna(int u) 
{ 
  int c = Foo<T>::a * 4; // This works
  return (a + b) * u;    // This doesn't
}
在Foo中,我得到一个错误

test.cpp:25: error: there are no arguments to A that depend on a template parameter, so a declaration of A must be available
test.cpp:25: error: (if you use -fpermissiveâ, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
当我尝试在Bar的成员函数中使用它时。
我也觉得奇怪:Bar继承了Foo,所以我认为很明显,Bar范围内的A()是Foo::A()。

更高版本的GCC正确地实现了该标准

该标准规定模板中的非限定名称是非依赖的,并且在定义模板时必须查找。依赖基类的定义在当时是未知的(基类模板的专门化可能存在),因此无法解析非限定名称

对于基类中声明的变量名和函数名都是如此

正如您所观察到的,解决方案是提供变量或函数的限定名称,或者提供“使用”声明。例如

template<class T> 
int Bar<T>::Perna(int u) 
{ 
  int c = Foo<T>::a * 4; // This works
  c = this->a * 4; // and this

  using Foo<T>::a; 
  c = a * 4; // and with 'using', so should this
}
模板
内部条形图::Perna(内部u)
{ 
int c=Foo::a*4;//这很有效
c=这个->a*4;//还有这个
使用Foo::a;
c=a*4;//对于“using”,这也应该
}

(事实上,我不能100%确定使用版本的正确语法,也不能从这里进行测试,但您已经知道了)。

GCC给出的错误消息表明,您的GCC版本仍然存在一个只在GCC4.7主干版本中解决的错误。包括GCC4.1在内的旧版本将乐于接受以下代码

template<typename T>
struct A {
  void f(int) { }
};

template<typename T>
struct B : A<T> {
  void g() { T t = 0; f(t); }
};

int main() {
  B<int> b; b.g();
}
模板
结构A{
空f(int){}
};
模板
结构B:A{
void g(){T T=0;f(T);}
};
int main(){
B;B.g();
}
GCC将在基类
A
中的
f(t)
中查找
f
,并在基类中找到声明。GCC之所以这样做,是因为
f
是依赖的,因为
f
有一些参数“依赖于模板参数”(查看它给您的错误消息!)。但该标准禁止GCC这样做有两个原因

  • 该标准指出,使用非限定名称永远不会在依赖基类中找到声明,无论该名称是否依赖

  • 该标准规定,在实例化时依赖函数名的查找只能进行ADL


  • GCC 4.7在这方面正确执行了标准。

    谢谢。我将袖手旁观并更改代码。我相信您必须在类级别执行using语句,即模板栏:public Foo{using Foo::a;…};
    template<class T> 
    int Bar<T>::Perna(int u) 
    { 
      int c = Foo<T>::a * 4; // This works
      c = this->a * 4; // and this
    
      using Foo<T>::a; 
      c = a * 4; // and with 'using', so should this
    }
    
    template<typename T>
    struct A {
      void f(int) { }
    };
    
    template<typename T>
    struct B : A<T> {
      void g() { T t = 0; f(t); }
    };
    
    int main() {
      B<int> b; b.g();
    }