C++ C++;对未实例化模板的标准要求
因此,我尝试编译下面的代码,但失败了(如预期的那样): 但是,如果我删除这一行,编译器编译它时不会出现任何错误(这也是意料之中的,因为不知道C++ C++;对未实例化模板的标准要求,c++,templates,template-instantiation,C++,Templates,Template Instantiation,因此,我尝试编译下面的代码,但失败了(如预期的那样): 但是,如果我删除这一行,编译器编译它时不会出现任何错误(这也是意料之中的,因为不知道T类型是否有random\u name()方法) 对于未使用(未实例化)的模板的诊断似乎在某种程度上是由实现定义的。但该标准可能对此类情况有一些要求。例如,在没有任何错误的情况下编译下面的代码是否符合标准 我试图在网站上搜索答案,但找不到任何相关问题 template <class T> int foo() { some ill-form
T
类型是否有random\u 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>();
}
模板
int foo(){
一些格式错误的代码
返回T::random_name();
}
模板
int foo(){return 0;}
int main(){
返回foo();
}
这是一个实施质量问题,其格式不正确,但如果未实例化,则无需根据以下内容进行诊断:
可以在任何实例化之前检查模板的有效性。
[ 注意:知道哪些名称是类型名称,可以通过这种方式检查每个模板的语法。
— 尾注
]
程序格式不正确,无需诊断,如果:
- 如果模板中的语句未实例化,则无法为模板或constexpr的子语句生成有效的专门化,或者
/permissive-
会改变这一点。clang甚至有一个使用-fdelayed模板解析
我们可以看到,clang不再生成诊断,但MSVC生成了诊断。这是一个实施质量问题,它的格式不正确,但如果未实例化,则不需要按照以下要求进行诊断:
可以在任何实例化之前检查模板的有效性。
[ 注意:知道哪些名称是类型名称,可以通过这种方式检查每个模板的语法。
— 尾注
]
程序格式不正确,无需诊断,如果:
- 如果模板中的语句未实例化,则无法为模板或constexpr的子语句生成有效的专门化,或者
我们可以看到MSVC没有诊断这种情况。这是因为使用/permissive-
会改变这一点。clang甚至有一个使用-fdelayed模板解析
我们可以看到,clang不再产生诊断,但MSVC产生了诊断。函数模板中的名称要么是依赖的,即实体以某种形式依赖于模板参数,要么是独立的,即没有迹象表明它依赖于模板参数e在定义函数模板
时查找。依赖名称在模板
实例化过程中查找,即在定义函数模板
时不需要定义名称。未能查找名称是一个错误。此过程的详细信息更为复杂,并且占据了大部分时间关于模板的章节
在您的情况下,some
是一个独立的名称,而T::
限定使random\u name
成为一个从属名称。函数模板
中的名称要么是从属的,即实体以某种形式依赖于模板
参数,要么是独立的,即没有标记说明它取决于模板
参数。定义函数模板
时会查找独立名称。在模板
实例化过程中会查找从属名称,即在定义函数模板
时不需要定义名称。未能查找名称是一种错误错误。此过程的细节更为复杂,占据了template
s一章的大部分内容
在您的例子中,some
是一个独立的名称,而T::
限定使random\u name
成为一个依赖名称。这条规则非常混乱。template somespecialerror{static\u assert(always\u false::value);}
非常常见,但这条规则似乎适用。也就是说,如果SomeSpecialError
没有实际实例化,这是格式不正确的,NDR.@lilistence-这条规则不适用。alwsys_false
可能仍然有一个专门化产生一个真值。这是一个非推断上下文,有原因。@Storytler如果这是真的,那么“且模板未实例化”部分似乎是多余的,因为模板永远不会按照其定义实例化。在我之前的评论中,我认为这句话的意思是“它在整个翻译单元中未实例化”,如果它指的是整个TU,编译器拥有所有的知识来确定是否存在always\u false
@lilistence的其他专门化-这不是多余的。这里的要点是,在不实例化模板的情况下,可以判断构造的格式不正确。但是使用always\u false
就永远无法判断专门化不会存在。@StoryTeller我相信你是对的。我只是想措辞应该更清楚,因为整个[temp.res]/8节都在讨论模板定义中的格式错误,没有实例化是从该节的上下文中暗示出来的。这条规则非常混乱。template somespecialerror{static\u assert(总是_false::value);}
非常常见,但这条规则似乎适用。也就是说,如果SomeSpecialError
没有实际实例化,这是格式不正确的,NDR。@lilistence-这条规则不适用。alwsys_false
可能仍然有一个专门化产生一个真值。这是一个非推断上下文,是有原因的。@Storytler如果这是真的,则不是
template <class T>
int foo() {
some ill-formed code
return T::random_name();
}
template <>
int foo<int>() { return 0; }
int main() {
return foo<int>();
}