子类的模板子类中的 C++ 名称解析

C++ Name Resolution in Template Subclass-of-Subclass

我试图在不使用 "this" 指针的情况下访问我的 C++ 代码中的 base-class 数据。我的 classes 是模板化的,ClassAClassB 的基础 class,它是 ClassC 的基础 class。所有 classes 都是 publicly 从它们的基础 classes 派生出来的。我发现这个讨论让我中途找到了一个解决方案,但并没有完全解决它:

Why do I have to access template base class members through the this pointer?

该页面表明我应该能够使用 "using" 语句解决我的问题。这是我正在尝试做的一个例子:

#include <iostream>

template <typename FP>
class ClassA
{
    protected:
    FP a ;
} ;

template <typename FP>
class ClassB : public ClassA <FP>
{
    using ClassA <FP> :: a ;
    public:
    void fooB ( void ) { std:: cout << a << std::endl ; }
} ;

template <typename FP>
class ClassC : public ClassB <FP>
{
    using ClassA <FP> :: a ;
    public:
    void fooC ( void ) { std:: cout << a << std::endl ; }
} ;

int main ( int argc, char *argv[] ) 
{
    ClassB <double> tempB ;
    ClassC <double> tempC ;

    tempB.fooB ( ) ;
    tempC.fooC ( ) ;

    return 0 ;
}

上面的代码编译失败,出现以下错误:

stepTWO.cpp: In instantiation of ‘class ClassC<double>’:
stepTWO.cpp:30:25:   required from here
stepTWO.cpp:8:12: error: ‘double ClassA<double>::a’ is protected
         FP a ;
            ^
 stepTWO.cpp:20:11: error: within this context
     class ClassC : public ClassB <FP>

我发现 "using" 将使变量可以在 ClassB 中访问ClassC,但不是两者。如果我将 using 语句放在两个 classes 中,我会得到上面显示的错误。所有继承都是通过public推导完成的。

有谁知道解决这个问题的方法吗? (除了使用 "this" 或完全限定的范围名称来访问我的数据元素之外?)

您的问题是 ClassB 中的 using ClassA <FP> :: a ; 位于 class 的私有部分。这意味着派生 class 将无法访问它。你需要做的是把它放在一个受保护的部分,就像声明变量 ClassA 一样。这样做你会得到:

#include <iostream>

template <typename FP>
class ClassA
{
    protected:
    FP a ;
} ;

template <typename FP>
class ClassB : public ClassA <FP>
{
    protected:
    using ClassA <FP> :: a ; // protected so it can be inherited
    public:
    void fooB ( void ) { std:: cout << a << std::endl ; }
} ;

template <typename FP>
class ClassC : public ClassB <FP>
{
    using ClassA <FP> :: a ;
    public:
    void fooC ( void ) { std:: cout << a << std::endl ; }
} ;

int main ( int argc, char *argv[] ) 
{
    ClassB <double> tempB ;
    ClassC <double> tempC ;

    tempB.fooB ( ) ;
    tempC.fooC ( ) ;

    return 0 ;
}