c++ - 嵌套类是类模板中的依赖类型?
问题描述
考虑以下:
template<class> struct T
{
struct T1
{
struct T2
{
};
};
/*typename*/ T1::T2 m;
};
如果没有typename
,编译会失败,因为 T2 被认为是从属名称,因此不是类型。在查看了 C++17 草案标准 (N4659) 之后,我相信我已经确定了原因:
§ 17.6.2.1 ¶ 5
一个名称是当前实例化的成员,如果它是
- 一个非限定名称,当查找时,它指的是作为当前实例化的类或其非依赖基类的至少一个成员。
...
如果名称是当前实例化的成员,并且在查找时引用了作为当前实例化的类的至少一个成员,则该名称是当前实例化的依赖成员。
T1 是当前实例化的从属成员。T2 不是当前实例化的成员(它是 T1 的成员),
§ 17.6.2.1 ¶ 9.3
一个类型是依赖的,如果它是
......
- 一个嵌套类或枚举,它是当前实例化的依赖成员,
......
T1 是一个嵌套类,因此是一个依赖类型。
§ 17.6 ¶ 3
当qualified-id旨在引用不是当前实例化(17.6.2.1)成员的类型并且其nested-name-specifier引用依赖类型时,它应以关键字typename为前缀,形成一个类型名说明符。...
因此,typename
需要。
我的理解正确吗?如果是这样,这背后的理由是什么?除了嵌套在 T1 中的 T2 之外,查找如何T1::T2
找到任何东西?
解决方案
是的,你是对的。
在您的情况下,这无关紧要,因为如果T1
不实例化m
(因为它是类成员),您就不可能专门化。但是你可以这样做,放入m
一个函数:
template<class> struct T
{
struct T1
{
struct T2
{
};
};
void foo() {
typename T1::T2 m;
}
};
template<>
struct T<void>::T1 {
int T2;
};
如果T1
不依赖,您的代码可能会改变含义,因为T2
将引用一个值而不是类型。
推荐阅读
- javascript - React Msal Dose 不返回 Web API 自定义范围
- stripe-payments - Stripe API - 如何在客户帐户中添加付款方式时获取?
- javascript - 从 js 到 html 的变量以在死亡和重新启动游戏场景/phaser-js 后保存 max 的值/丢失值
- javafx - 从 JavaFX 中的 2D 选择框获取 3D 网格视图
- apache - 在本地计算机上托管 Web 使用 xampp
- performance - 通过 Powershell 脚本减少内存消耗
- python - 使用 Big Query API 将数据摄取到按时间分区的表中,但出现 SyntaxError: Unexpected end of input
- r - 闪亮的应用程序使用查询字符串中的默认值?
- javascript - 如何在 Sequelize Model 中创建方法?
- c - 如何使用开关来偏移 for 循环的开始?