c++ - 从非实例化的上下文中引用特定的模板特化:实例化与否?
问题描述
考虑以下示例
template <typename A> struct S
{
A a;
void foo() {}
};
template <typename T> void bar()
{
S<void> *p = 0;
}
template <typename T> void baz()
{
S<void>{}.foo();
}
template <typename T> void qux()
{
S<void> s{};
}
int main()
{
}
函数模板bar
,baz
并且qux
故意不实例化。
baz
由于“明显”原因无法在 GCC 和 Clang 中编译的定义-S<void>
是S
. 但是,在这种情况下哪种语言规则有效?
一方面,
S<void>
不依赖 的模板参数baz
,成员访问要求它是完整的,这就触发了 的实例化S<void>
,失败了。需要诊断。另一方面,我们有“如果不能为非实例化模板生成有效的特化,则代码格式错误”的总括规则。这使得定义
baz
不正确。但是,不需要诊断。
更具体地说,我的假设是否正确(如 #1 中所表达),即上述S<void>
来自非实例化的引用baz
需要实例化S<void>
? bar
两个编译器都乐于接受 的 定义,它不实例化,这一事实支持了这一假设S<void>
。
但是,上述编译器对qux
Clang 抱怨的处理方式不同,而 GCC 则毫无抱怨地接受它。这是其中一个编译器中的错误吗?在这种情况下是否需要诊断?还是我假设#1 在这里工作是错误的?如果#2 是诊断的基础,那么编译器之间的差异是可以接受的。
解决方案
对于baz
和qux
,表达式包括的有效性S<void>
只能通过 S 的实例化来完成。然而,编译器没有义务在任何实例化之前执行此验证[temp.res]/8
可以 在任何实例化之前检查模板的有效性。[...] 程序格式错误,无需诊断,如果:
- 由于不依赖于模板参数的构造,紧随其定义的模板的假设实例化将是格式错误的,
推荐阅读
- sql-server - SSIS - 如何将日期时间变量传递给存储过程
- r - 如何创建具有相同 y 轴的两个变量(死的和活的)的箱线图?
- eyeshot - 是否可以仅将纹理应用于网格的一部分?
- python - 二维数组在 python 中不能正常工作
- reactjs - 从 excel 导入特定数据列并在 Reach Application 中显示
- mysql - 由于删除查询 - 基于行的复制,从属服务器中的 MySQL 复制滞后
- r - 如果后跟 R 中的空行,则将多行数据帧合并在一起
- architecture - 是否可以像这样构建我的 Axon 项目?
- android - 向所有 React Native 应用程序发送“重新加载”失败 IOS
- r - 从 sf 线串对象创建具有正确索引标签的 inla.graph 对象