c++ - 查找规则如何应用于类模板中默认成员初始值设定项中使用的名称?
问题描述
#include <iostream>
template<class T>
struct A{
int c = T::a;
};
struct B{
A<B> cc;
static const int a = 0;
};
int main(){
}
GCC 和 Clang 都接受上面的例子。关于查找规则如何应用于类模板特化中的名称,该名称可能是导致类模板特化的隐式实例化的类的成员,在 c++20 或更早版本中尚不清楚。幸运的是,在目前的草案中已经很清楚了。
[basic.lookup#class.member.lookup-3]
如果 P 在 C 的完整类上下文中,则声明集是在 C 的范围内从紧随 C 的类说明符之后的 N 的单个搜索的结果,否则从P搜索。如果结果声明集不为空,则子对象集包含 C 本身,计算完成。
似乎该规则可以用于解释我在上面所说的大多数情况,但是,考虑上面的示例,它有点特殊。
非静态成员的定义cc
会导致 specialization 的隐式实例化,A<B>
此时,它还不是 class 的完整上下文B
。因此,后续在范围内查找名称B
应该从这一点开始。如果T::a
用作类 template 的非静态成员的类型说明符,则A
100% 确定编译器会报告一个错误,即a
在B
.
但是,除了以下规则
temp.res#general-1
如果名称是依赖的(如 [temp.dep] 中指定的),则为每个特化(替换后)查找它,因为查找取决于模板参数。
我在标准中找不到任何措辞来说明隐式实例化是否A
会导致查找规则应用于默认成员初始化程序中的名称,或者不在该点。
乍一看上面的规则,应该是指在实例化封闭类模板特化时要查找名称,然后a
在范围内找不到,B
因为此时它不被认为是一个完整的类,只有P
可以找到这些可以到达的声明。
显然,GCC 和 Clang 考虑的行为T
是一个完整的类型,a
可以在T
. 换句话说,这些编译器似乎不会立即执行实例化时间的T::a
查找A
。如果我错过了某个特殊规则,请指出。
解决方案
推荐阅读
- php - WP Gravity Forms - 当等于 ,00 时隐藏小数
- angular - 从 http Post 返回 Observable
- java - 在火花中对多维数据集数据集使用连接时是否有任何限制
- hyperledger-fabric - 当 2 个服务器相互断开然后重新连接时会发生什么?
- python - Kivy 1.10.1 如何使用选项设置更改某些东西的 font_size?
- java - 如何理解 Android Studio 中的 Kotlin 文档语法
- java - 如何将自定义对象传递给不同片段中的列表?
- android-ffmpeg - 如何使用 ffmpeg 通过 https 下载视频文件
- ios - 如何提高 AVplayer 的加载率
- msp430 - MSP430 的 IAR 嵌入式工作台中的 MACRO 符号使用