简体   繁体   English

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

[英]Why can't the class inherit the member types of its parents?

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
}

Why can't the class inherit the member types of its parents?为什么 class 不能继承其父级的成员类型?

The member U is inherited like any other member would be, irrespective of which classes are templated, but it is not found by unqualified name lookup according to C++17 [temp.dep]/3:成员U像任何其他成员一样被继承,无论模板化了哪些类,但根据 C++17 [temp.dep]/3,未通过非限定名称查找找不到它:

In the definition of a class or class template, the scope of a dependent base class (17.6.2.1) is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member. In the definition of a class or class template, the scope of a dependent base class (17.6.2.1) is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or成员。

Here, A<T> is a dependent base class since it depends on the template parameter T of the class template D .这里, A<T>是一个依赖基础 class 因为它依赖于 class 模板D的模板参数T

To force the compiler to look up U in the base class, you have to use qualified name lookup.要强制编译器在基础 class 中查找U ,您必须使用限定名称查找。 You can do it like this:你可以这样做:

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

Another way of expressing it, if the template arguments to the base class are complicated, is:另一种表达方式是,如果模板 arguments 到基础 class 很复杂,则为:

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

If you are going to be writing this out multiple times then you could also redeclare the type in D for convenience:如果你要多次写出来,那么你也可以为了方便重新声明D中的类型:

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

Note: in the above contexts, typename will become optional in C++20.注意:在上述上下文中, typename在 C++20 中将变为可选。

Because as a non-dependent name, U won't be looked up in dependent base class A<T> , which depends on template parameter T .因为作为非依赖名称, U不会在依赖基础 class A<T>中查找,这取决于模板参数T On the other hand, for both B and C their base class are non-dependent base class.另一方面,对于BC ,它们的基础 class 是非依赖基础 class。

You can change to dependent name, eg A<T>::U , which depends on template parameter T too.您可以更改为依赖名称,例如A<T>::U ,这也取决于模板参数T Dependent names may be looked up only at the time of instantiation, at that time the exact specialization (including base class) will be known.依赖名称只能在实例化时查找,那时确切的专业化(包括基类)将是已知的。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么一个类成员函数不能接受与其类相同类型的多个参数 - Why can't a class member function take more than one argument of the same type as its class 成员类可以从它的父级继承吗? - Can a member class inherit from it's parent? 为什么类不能从decltype的结果继承? - Why can't a class inherit from the result of a decltype? C ++:从类及其受保护的成员类型继承是否可以? - C++: Is It OK to Inherit from a Class and Its Protected Member Type? 为什么我的类构造函数不是初始化其成员变量? - Why isn't my class constructor initializing its member variables? 为什么子类的子类不能访问其祖先的受保护成员? - Why can't a subclass of a subclass access protected member of its ancestor? 为什么不能将boost :: hana :: overload_t成为类的成员 - Why can't boost::hana::overload_t be a member of a class 为什么数据成员不继承钻石问题 c++ - Why doesn't data member inherit in a diamond problem c++ 如果不知道其参数类型,如何默认一个特殊成员 function? - How can one default a special member function if one doesn't know its parameter types? 模板化嵌套C ++类可以继承其封闭类吗? - Can a templated nested C++ class inherit its enclosing class?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM