为什么在模板函数中使用"using namespace xxx"无效?

5
namespace ns1
{
    template <class T>
    void f(T)
    {
        cout << typeid(T).name() << endl;
    }
};

using namespace ns1;

namespace ns2
{
    void f(int)
    {
        cout << "int" << endl;
    }

    void test()
    {
        f(vector<int>()); // Error! 
        // Why not call ns1::f<vector<int>>(vector<int>()); ???
    }
};
4个回答

9
这与模板无关,而是与名称查找有关。标准中在3.4/1(名称查找)中表示:
名称查找应该为名称(见10.2)找到一个明确的声明。如果名称是函数名,则名称查找可能将多个声明与一个名称相关联;这些声明被称为一组重载函数(13.1)。在名称查找成功后执行重载分辨率(13.3)。只有在名称查找和函数重载分辨率(如果适用)成功之后才考虑访问规则(第11条)。
在3.4.1(未限定名称查找)中表示:
名称查找一旦找到名称的声明就结束。
在您的情况下,`f`是一个未限定名称。它在当前作用域中搜索,在`ns2`命名空间中找到了一个声明。名称查找在此处结束,然后进行重载分辨率:候选集中没有匹配参数类型为`std::vector`的重载函数,因此程序是非法的。

非常感谢您。您的回答总是快速而准确的。 - xmllmx

2

因为当你在命名空间(ns2)内部时,如果名称未被限定,它将优先于任何其他命名空间。


2

由于您目前在ns2名称空间中,因此ns2将具有优先权。为什么编译器会认为您真正想要调用的是ns1::f()?


1

这应该可以工作:

namespace ns1
{
    template <class T>
    void f(T)
    {
        cout << typeid(T).name() << endl;
    }
};



namespace ns2
{
    using ns1::f;
    void f(int)
    {
        cout << "int" << endl;
    }

    void test()
    {
        f(vector<int>()); // Error! 
        // Why not call ns1::f<vector<int>>(vector<int>()); ???
    }
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接