C++ c++;:模板中非限定名称查找的上下文

C++ c++;:模板中非限定名称查找的上下文,c++,templates,namespaces,argument-dependent-lookup,C++,Templates,Namespaces,Argument Dependent Lookup,我试图参考标准中关于do_run的解决方案,发现“对于使用非限定名称查找(3.4.1)或限定名称查找(3.4.3)的查找部分,仅适用于” 找到模板定义上下文中的函数声明”。具体的背景是什么 在下面的示例中,do\u run(int)以某种方式“隐藏”do\u run(domain::mystruct),编译器抱怨o无法转换为int。如果我注释掉do_-run(int),do_-run(domain::mystruct)将对run可见,并编译代码。该行为是否与标准中提到的“上下文”相关?在我看来,

我试图参考标准中关于do_run的解决方案,发现“对于使用非限定名称查找(3.4.1)或限定名称查找(3.4.3)的查找部分,仅适用于” 找到模板定义上下文中的函数声明”。具体的背景是什么

在下面的示例中,
do\u run(int)
以某种方式“隐藏”
do\u run(domain::mystruct)
,编译器抱怨
o无法转换为int
。如果我注释掉
do_-run(int)
do_-run(domain::mystruct)
将对
run
可见,并编译代码。该行为是否与标准中提到的“上下文”相关?在我看来,
do_run(int)
do_run(domain::mystruct)
应该对(可解析的)run可见

命名空间域{
结构mystruct{};
}

void do_run(domain::mystruct){cout查找取决于它是否是依赖名。由于函数调用取决于模板参数类型
T
(通过使用此类型的对象
T
调用),因此它是依赖名

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

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

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


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

好的,如果定义了lib::details::do_run(int),则找不到do_run(domain::mystruct)。我想我应该在另一个编译器上尝试。是的,这是一个编译器问题。代码如下所示(添加了明显的标题和使用指令)确实使用gcc编译。谢谢,我验证了它是在GCC4.7中编译的。
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;
}