c ++:模板中非限定名称查找的上下文 [英] c++: the context of an unqualified name lookup in a template

查看:91
本文介绍了c ++:模板中非限定名称查找的上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I tried to consult the standard on the resolution of do_run, and found "For the part of the lookup using unqualified name lookup (3.4.1) or qualified name lookup (3.4.3), only function declarations from the template definition context are found". What exactly is the context?

在下面的示例中,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)都应该对运行(可解析)可见.

In the following example, do_run(int) somehow "hides" do_run(domain::mystruct), and the compiler complains that o can't be converted to int. If I comment out do_run(int), do_run(domain::mystruct) becomes visible to run, and the code is compiled. Is this behavior related to the "context" referred to in the standard? Seems to me both do_run(int) and do_run(domain::mystruct) should be visible to (resolvable) run.

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)带入上下文".有三种方法:

In the presence of do_run(int), I need an extra step to bring do_run(domain::mystruct) into the "context". there're three ways:

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

所以我推断出上下文是名称空间lib :: details和名称空间域?

So I deduced the context is namespace lib::details and namespace domain?

编译器VS2010

推荐答案

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

The look-up depends on whether it is a dependent name or not. Since your function call depends on the template argument type T (through being called using the object t of this type), it is a dependent name.

仅在定义模板的上下文中查找非相关名称.不会考虑与实际实例化相关的任何事情:由于名称的确定不取决于模板参数,因此没有必要考虑实例化.这是我的查找阶段.

Non-dependent names are just looked up in the context where the template is defined. Anything relating to the actual instantiation is not taken into consideration: Since the name is determined as not depending on the template argument, it wouldn't make sense to take the instantiation into account. This is phase I look-up.

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

Dependent function names are looked up taking the instantiation into account. This uses all arguments and determines associated namespaces to look up functions in these associated namespace only. For built-in types, the associated namespace added is the global namespace. For other types, the associated namespaces added are the namespace they live in plus all enclosing namespace. In addition, the associated namespace of things visible from the class definition are added: the associated namespaces of base classes, for templates the namespaces of the template arguments, etc. This is phase II look-up and also called argument dependent look-up (I think the terms are not entirely identical and the details are not as easy as described above, of course).

在您引用的代码中,很明显,在全局范围内的do_run()函数是在全局命名空间中为lib::details::runner<domain::mystruct>找到的.如果将其移至domain,也会找到它.在实例化lib::details::runner<int>中找不到找不到的命名空间lib::details中的do_run()方法,但是:与int关联的命名空间只是全局命名空间,而函数不存在且直到实例化时才查找,因为它是一个从属名称.

In the code you quoted, the do_run() function in the global scope is, obviously, found for lib::details::runner<domain::mystruct> as it is in the global namespace. It would also be found if it were moved to domain. The do_run() method in namespace lib::details is not found in an instantiation lib::details::runner<int>, however: the associated namespaces for int are only the global namespace but the function isn't there and it isn't looked up until instantiation because it is a dependent name.

也就是说,我的理解是MSVC ++不会以指定的方式实现两阶段名称查找,但是我不知道它以哪种方式偏离.

That said, my understanding is that MSVC++ doesn't implement two-phase name look-up the way it is specified but I don't know in which ways it deviates.

这篇关于c ++:模板中非限定名称查找的上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆