在c ++标准[temp.point]中,其写为:
表达式的实例上下文,取决于 模板参数是具有外部链接的声明的集 在模板实例化点之前声明 在同一个翻译部门进行专业化。
然后在[临时候选人]:
对于使用关联名称空间的部分查找 ([basic.lookup.argdep]),在中仅找到函数声明 模板定义上下文或模板实例化上下文 找到。
这是否意味着以下代码应该失败:
namespace A{
struct S{};
}
template<class T>
void g(T a){
f(a); //f will be found by argument dependent lookup
}
namespace A{
static void f(S); //but f doesn't have external linkage
}
void test(A::S i){
g(i);
}
//point of instantiation of g
//A::f(S) doesn't have external linkage
//=> so it's not in the instantiation context of template g ??
此代码实际上可以编译,那么此标准段是什么意思?
答案 0 :(得分:8)
这是标准中的缺陷。最初在core issue 561中提到,委员会对此进行了判断
2006年4月会议上的笔记:
该小组的共识是[..]应该通过查找找到内部链接函数(尽管如果通过重载解决方案选择它们可能会导致错误)。
不幸的是,相应的修补程序不足,如core issue 1258所述:
C ++ 11扩展了相关函数调用的查找规则(17.7.4.2 [temp.dep.candidate]第1条第2项),以包括具有内部链接的函数;以前只考虑具有外部链接的功能。但是,17.7.4.1 [温度点]第6段仍然说,
依赖于模板参数的表达式的实例化上下文是具有外部链接的声明集,该声明是在同一翻译单元中模板专业化的实例化点之前声明的。
大概这个措辞被忽略了,应该与新规范保持一致。
也就是说,第二个引用段落的前面的措辞是
对于使用关联命名空间(3.4.2)的查找,仅具有外部链接的函数声明 在模板定义上下文或模板实例化上下文中找到了
。
..已针对C ++ 11进行了修改,但是该更改错过了您的第一个引用,因此变得毫无意义。目的是不区分具有内部链接的功能。