所以我尝试编译下面的代码,但失败了(如预期的那样):
1.cpp: In function ‘int foo()’:
1.cpp:3:5: error: ‘some’ was not declared in this scope
some ill-formed code
^
但是,如果我删除了这一行,编译器将对其进行编译而不会出现任何错误(由于不知道T
类型是否具有random_name()
方法,这也是可以预期的。
似乎对未使用(未实例化)模板的诊断在某种程度上定义了实现。但是也许标准对这种情况有一些要求。例如,编译下面的代码没有任何错误是否符合标准?
我试图在网站上搜索答案,但是找不到任何相关问题。
template <class T>
int foo() {
some ill-formed code
return T::random_name();
}
template <>
int foo<int>() { return 0; }
int main() {
return foo<int>();
}
答案 0 :(得分:4)
这是一个实施质量问题,格式错误,但是如果未实例化,则按照[temp.res#8.1]p不需要诊断:
可以在任何实例化之前检查模板的有效性。 [注意:知道哪些名称是类型名称,这样就可以检查每个模板的语法。 —注 ] 程序格式错误,无需诊断,如果:
- 如果模板中的语句或constexpr的子语句未实例化,则无法为该模板或constexpr的子语句生成有效的专业化,或者
,我们可以看到from this live godbolt example MSVC无法诊断这种情况。这是因为MSVC is not using two-phase lookup但使用/permissive-
会改变这一点。铛甚至有MSVC compatibility mode to emulate this使用-fdelayed-template-parsing
。
我们可以看到from this live godbolt using these two options不再发出诊断信息,但MSVC发出诊断信息。
答案 1 :(得分:0)
template
中的名称或者是依赖的,即实体依赖于template
参数的某种形式,或者是无关的,即没有迹象表明它取决于template
参数。定义函数template
时将查找独立名称。在template
实例化过程中查找从属名称,即,在定义函数template
时无需定义名称。无法查找名称是错误。此过程的细节涉及更多,并占据了template
s上的大部分章节。
在您的情况下,some
是一个独立名称,而T::
限定条件使random_name
是一个从属名称。