c++:模板中不合格名称查找的上下文

c++: the context of an unqualified name lookup in a template

本文关键字:查找 上下文 不合格 c++      更新时间:2023-10-16

我试图查阅关于do_run分辨率的标准,发现"对于使用非限定名称查找(3.4.1)或限定名称查找的部分(3.4.3),仅找到模板定义上下文中的函数声明"。上下文到底是什么?

在下面的示例中,do_run(int)以某种方式"隐藏"了do_run(domain::mystruct),而编译器则抱怨o can't be converted to int。如果我注释掉do_run(int),则do_run(domain::mystruct)run可见,并且代码被编译。这种行为是否与标准中提到的"上下文"有关?在我看来,do_run(int)do_run(domain::mystruct)都应该对运行可见(可解析)。

namespace domain {
struct mystruct { };
}
void do_run(domain::mystruct) { cout << "do_run(domain::mystruct)" << endl; } 
namespace lib { namespace details {
template <class T>
class runner { 
public:
void run(T t) { do_run(t); }
};
void do_run(int) { cout << "do_run(int)" << endl; } 
}}
int main() {
domain::mystruct o;
lib::details::runner<domain::mystruct> r;
r.run(o);
return 0;
}

do_run(int)存在的情况下,我需要额外的步骤将do_run(domain::mystruct)引入"上下文"。有三种方法:

  1. do_run(domain::mystruct)放入命名空间域
  2. do_run(domain::mystruct)放入命名空间lib::details中
  3. 在命名空间lib::details中添加using ::do_run

所以我推断上下文是namespace lib::details和namespace domain?

编译器VS2010

查找取决于它是否是依赖名称。由于函数调用依赖于模板参数类型T(通过使用此类型的对象t进行调用),因此它是一个依赖名称。

非依赖名称只是在定义模板的上下文中查找。任何与实际实例化相关的内容都没有被考虑在内:由于名称被确定为不依赖于模板参数,因此将实例化考虑在内是没有意义的。这是第一阶段的查找。

依赖函数名称是在考虑实例化的情况下查找的。这将使用所有参数并确定关联的命名空间,以便仅在这些关联的命名空间中查找函数。对于内置类型,添加的关联命名空间是全局命名空间。对于其他类型,添加的关联命名空间是它们所在的命名空间加上所有封闭的命名空间。此外,还添加了从类定义中可见的事物的关联命名空间:基类的关联命名空间,对于模板,模板参数的命名空间等。这是第二阶段查找,也称为参数相关查找(当然,我认为术语不完全相同,细节也不像上面描述的那么容易)。

在您引用的代码中,全局作用域中的do_run()函数显然是为lib::details::runner<domain::mystruct>找到的,因为它在全局命名空间中。如果将其移动到domain,也会发现它。命名空间lib::details中的do_run()方法是而不是在实例化lib::details::runner<int>中找到的:int的关联命名空间只是全局命名空间,但函数不存在,并且在实例化之前不会查找它,因为它是一个依赖名称。

也就是说,我的理解是MSVC++并没有按照指定的方式实现两阶段名称查找,但我不知道它偏离了哪些方面。