Почему «использование пространства имен xxx» не влияет на функции шаблона? - PullRequest
5 голосов
/ 15 декабря 2010
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 голосов
/ 15 декабря 2010

Это не имеет ничего общего с шаблонами, но без поиска имени.

Это то, что стандарт говорит в 3.4 / 1 (поиск имени):

Поиск имени должен найтиоднозначное объявление имени (см. 10.2).Поиск имени может связывать более одного объявления с именем, если он находит имя как имя функции;говорят, что объявления образуют набор перегруженных функций (13.1).Разрешение перегрузки (13.3) происходит после успешного поиска имени.Правила доступа (пункт 11) рассматриваются только после успешного поиска имени и разрешения перегрузки функции (если применимо).

И в 3.4.1 (поиск без определения имени):

поиск имени заканчивается, как только будет найдено объявление для имени

В вашем случае f - это неквалифицированное имя.Поиск производится в непосредственной области видимости и в пространстве имен ns2 , где находится объявление .На этом поиск имени заканчивается, и в игру вступает разрешение перегрузки: в наборе кандидатов отсутствует перегрузка, соответствующая типу аргумента std::vector<int>, поэтому программа некорректна.

2 голосов
/ 15 декабря 2010

ns2 будет иметь приоритет, поскольку это пространство имен, в котором вы сейчас находитесь. Почему компилятор должен думать, что вы действительно имели в виду ns1 :: f ()?

2 голосов
/ 15 декабря 2010

Потому что, когда вы находитесь внутри пространства имен (ns2), оно имеет приоритет над любыми другими, если имена не определены.

1 голос
/ 15 декабря 2010

Это должно работать:

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>()); ???
    }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...