c++ - 为什么类不能继承其父类的成员类型?
问题描述
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
}
为什么类不能继承其父类的成员类型?
解决方案
该成员U
像任何其他成员一样被继承,无论模板化了哪些类,但根据 C++17 [temp.dep]/3 的非限定名称查找找不到它:
在类或类模板的定义中,在非限定名称查找期间,无论是在类模板或成员的定义点,还是在类模板的实例化期间,都不会检查依赖基类 (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 中将变为可选。
推荐阅读
- reactjs - 我尝试让 webpack 在我的 create-react-app 中工作,但我收到了这个巨大的错误
- apache-flink - Flink - 如何在状态中聚合
- django - 如何从一个页面获取输入并将它们发送到 django 中的另一个页面
- django - 如何将 CustomUser 模型保存到另一个模型数据
- php - Laravel 7 上 Mailtrap 的值 null 问题的偏移量
- elasticsearch - 在 ElasticSearch 中查询和排除
- robotframework - 我们如何使用 Ride 在机器人框架中同时在不同的浏览器上运行测试用例
- angular - 角度防护没有触发路由
- html - 在导航栏中修复图像 | 引导程序
- python-3.x - 如何在 pyscipopt 中使用relax() 方法?