【问题标题】:Why can't the class inherit the member types of its parents?为什么类不能继承其父类的成员类型?
【发布时间】:2020-04-30 02:40:25
【问题描述】:
template<typename T>
struct A
{
    using U = int;
};

struct B : A<int>
{
    void f(U) // ok
    {}
};

template<typename T>
struct C : A<int>
{
    void f(U) // ok
    {}
};

template<typename T>
struct D : A<T>
{
    void f(U) // fatal error: unknown type name 'U'
    {}
};

int main()
{
    B      b; // ok
    C<int> c; // ok
    D<int> d; // error
}

为什么类不能继承其父类的成员类型?

【问题讨论】:

标签: c++ oop templates inheritance standards


【解决方案1】:

成员 U 像任何其他成员一样被继承,无论模板化了哪些类,但根据 C++17 [temp.dep]/3 的非限定名称查找找不到它:

在类或类模板的定义中,在非限定名称查找期间,无论是在类模板或成员的定义点还是在实例化类模板或成员。

这里,A&lt;T&gt; 是一个依赖基类,因为它依赖于类模板D 的模板参数T

要强制编译器在基类中查找U,您必须使用限定名称查找。你可以这样做:

void f(typename A<T>::U);

如果基类的模板参数很复杂,另一种表达方式是:

void f(typename D::A::U);

如果您要多次写出此内容,那么为方便起见,您还可以在 D 中重新声明类型:

using U = typename A<T>::U;
void f(U);

注意:在上述上下文中,typename 在 C++20 中将变为可选。

【讨论】:

    【解决方案2】:

    因为作为非依赖名称,U 不会在依赖基类@​​987654322@ 中查找,这取决于模板参数T。另一方面,BC 的基类都是非依赖基类。

    您可以更改为依赖名称,例如A&lt;T&gt;::U,这也取决于模板参数T。依赖名称只能在实例化时查找,届时将知道确切的特化(包括基类)。

    template<typename T>
    struct D : A<T>
    {
        void f(typename A<T>::U)
        {}
    };
    

    【讨论】:

      猜你喜欢
      • 2015-09-02
      • 2013-04-11
      • 1970-01-01
      • 1970-01-01
      • 2013-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多