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

时间:2020-04-30 02:40:25

标签: c++ oop templates inheritance standards

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
}

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

2 个答案:

答案 0 :(得分:4)

成员U就像任何其他成员一样被继承,而不管要对哪个类进行模板化,但是根据C ++ 17 [temp.dep] / 3,不合格的名称查找找不到它:< / p>

在类或类模板的定义中,在类模板或成员的定义时或在实例化类的实例的过程中,不合格名称查找期间不检查从属基类的范围(17.6.2.1)。课程模板或成员。

在这里,A<T>是一个依赖基类,因为它取决于类模板T的模板参数D

要强制编译器在基类中查找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中将变为可选。

答案 1 :(得分:3)

由于@font-face{ font-family: songenia; src:url("songenia.otf") } * { margin: 0; padding: 0; box-sizing: border-box; color: cornsilk; } body { font-family: songenia; font-size: xx-large; background-image: url(background.jpg); line-height: 1.2; } .input{ line-height: 1.6; margin-top: 30px; } .posts { list-style: none; } .onepost { padding: 10px; background: rgba(215, 177, 88, 0.548); margin: 30px 0; } header { background: rgba(215, 177, 88, 0.548); padding: 2rem; min-width: 100%; text-align: center; } h1, h4 { text-align: center; } .error-message { text-align: center; } .input { margin-top: 30px; font-size: large; } main { margin: auto; width: 500px; overflow: auto; padding: 3rem 2rem; } .post-form { padding: 2rem; background:rgba(215, 177, 88, 0.548); } .post-form label { text-align: center; display: block; } .post-form input[type='text'] { width: 100%; padding: 8px; margin-bottom: 10px; border-radius: 5px; color: black; border: 1px solid #ccc; } .btn { display: block; width: 100%; padding: 10px 15px; border: 0; background:rgba(25, 17, 68, 0.644); color: #fff; border-radius: 5px; margin: 5px 0; } .btn:hover { background: rgba(215, 177, 88, 0.548); } 是一个非依赖名称,因此不会在依赖基类U中查找,后者依赖于模板参数A<T>。另一方面,对于TB而言,它们的基类都是非依赖基类。

您可以更改为从属名称,例如C,它也取决于模板参数A<T>::U。依赖名称只能在实例化时进行查找,届时确切的专业名称(包括基类)将是已知的。

T
相关问题