我有两个奇怪的情况,似乎代码应该编译,但事实并非如此。首先,请考虑以下代码,该代码成功编译:
struct A
{
template <class T>
void member_func(T t)
{
global_func(t);
}
};
int main()
{
}
但是如果我通过前缀“::”来完全限定global_func,则它不会编译错误“'global_func'未在此范围内声明”:
struct A
{
template <class T>
void member_func(T t)
{
::global_func(t);
}
};
int main()
{
}
另外,如果我尝试将global_func传递给boost :: bind,它就不会编译(同样的错误):
#include <boost/bind.hpp>
class A
{
template <class T>
void member_func(T t)
{
boost::bind(global_func)(t);
}
};
int main()
{
}
为什么不在这些情况下编译?似乎没有实例化member_func()模板方法,所以它不应该找到缺少的函数错误。
答案 0 :(得分:10)
在第一个示例中,global_func
是从属名称,因为它是后缀()
表达式中使用的非限定名称,其中括号中的表达式取决于模板参数。这意味着必须推迟查找,直到模板被实例化为模板参数已知并且ADL可能有效的点。
在第二个示例中,::global_func
是一个限定名,因此它的查找不会延迟,必须查找定义模板的指针。
同样,在表达式boost::bind(global_func)
中,global_func
未在表达式中使用,该表达式依赖于模板参数,因此,查询不会延迟,并且声明必须在定义时可见成员模板。