Ser*_*rid 3 c++ templates clang clang++
在 C++ 中,函数模板的类型检查被推迟到调用(实例化)模板函数为止。例如
template<typename T>
int right() {
return T::f();
}
Run Code Online (Sandbox Code Playgroud)
是合法的 C++ 代码,之后right<Foo>()只要 typeFoo具有f返回int.
我观察到我的 C++ 编译器 (Clang) 可以捕获一些类型错误,只要它们不依赖于模板参数即可。例如
template<typename T>
int wrong1() {
return "";
}
Run Code Online (Sandbox Code Playgroud)
即使从未调用(实例化)模板函数,也无法使用 Clang 16.0.0 进行编译(char*与 不兼容)。int这就带来了一个问题:C++ 编译器是否要求模板函数声明类型正确(忽略依赖于模板参数的表达式)?或者它只是 Clang 的一个功能,它试图尽早捕获类型错误?
模板定义中的任何非依赖构造都会导致模板定义后立即假设实例化格式错误,从而使程序 IFNDR(格式错误,无需诊断),这意味着模板没有强加任何要求。关于编译器如何处理此类程序的 C++ 标准。
在这种情况下,即使模板没有实际实例化,编译器也可以立即退出编译并出现错误,或者编译器可能会忽略它并仅在模板实际实例化时提供诊断。(从技术上讲,它还可以做任何其他事情,例如编译程序但让它以意想不到的方式运行。IFNDR 实际上与所有输入的未定义行为相同。)
还有一些其他情况,可以在定义时检查模板定义的有效性,如果不满足[temp.res.general]/8中列出的某些要求,则导致程序成为 IFNDR 。例如,如果模板实际上并未实例化,但模板的任何实例化都将是格式错误的。
但除了列出的情况之外,不允许编译器退出编译或对可以实例化有效专业化的模板发出诊断。
“非依赖”具有与构造是否依赖于模板参数相关的特定技术含义。有关参考,请参阅https://en.cppreference.com/w/cpp/language/dependent_name以及标准(草案)中的[temp.dep] 。
在您的示例中T::f是一个依赖名称,但第二个示例中的表达式""和返回类型不依赖于(类型/值)。此外,不可能在第二个示例中专门化模板,以便从""到int返回值的转换格式良好,而可以T在第一个示例中定义并传递类型,以便实例化格式良好。
| 归档时间: |
|
| 查看次数: |
111 次 |
| 最近记录: |