c++ - 为什么即使直到最后才定义实际类型,从属名称也可以被认为是完整的
问题描述
template <class T>
void Yeap(T);
int main() {
Yeap(0);
return 0;
}
template <class T>
void YeapImpl();
struct X;
template <class T>
void Yeap(T) {
YeapImpl<X>(); // pass X to another template
}
template <class T>
void YeapImpl() {
T().foo();
}
struct X {
void foo() {}
};
请注意,struct X
直到最后才定义。我曾经相信所有使用 odr 的名称在实例化时都必须是完整的。但是在这里,编译器如何在定义之前将其视为完整类型?
我已经检查了 cppreference 中依赖名称和函数模板实例化的绑定规则和查找规则,但它们都无法解释这里发生了什么。
解决方案
我相信这个程序格式不正确,不需要诊断。
[temp.point]/8读取,编辑掉不相关的部分:
函数模板的特化 [...] 可能在翻译单元内具有多个实例化点,并且除了上述实例化点之外,对于在翻译单元内具有实例化点的任何此类特化,结束翻译单元也被认为是一个实例化点。[...] 如果两个不同的实例化点根据单一定义规则赋予模板特化不同的含义,则程序格式错误,不需要诊断。
YeapImpl<X>
有两个实例化点:在问题的注释行和翻译单元的末尾调用它。在实例化的第一点,X
是不完整的,这会使函数的主体格式不正确。在实例化的第二点中,X
是完整的,这使得主体结构良好。
这两个专业有[非常]不同的含义。
推荐阅读
- c# - 连接两个表时出现 System.InvalidOperationException
- c# - 在网格中插入带有 ItemsControl 的标签
- r - 如何在 R 中创建并排条形图?(-0.01 * 高度中的错误:二元运算符的非数字参数)
- javascript - 直播聊天示例块抛出错误。Messagelist = messages.entries 不是函数
- typescript - 最后一张幻灯片未调用 Ionic 5 Slides ionSlideDidChange
- html - 如何在固定宽度的 div 中并排放置图像
- python - 如何获取两个文件之间的相对(“../x”)路径?
- javascript - 检查网页是否包含不定式滚动?
- javascript - 在测试承诺拒绝时,在将 Mocha 与 chai-as-promised 一起使用时获得“不是一个 thenable”
- java - Drools:访问 ArrayList 作为 Map 中的值