Как этот код может вызвать неоднозначность между NS1::format и ns3:: format?

Импортируется ли формат, поскольку он использует импортированный класс объектов?
Но с той же логикой класс не импортируется, если он использует импортированный класс объектов.

namespace NS1  {
    class Object { /* ... */ };
    int format(const Object&) { std::cout << "NS1"; }
    namespace NS2  {
        class Object { /* ... */ };
        int format(const Object&) { std::cout << "NS2"; }
    }
}

namespace NS3  {
    using NS1::Object;
    int format(const Object&) { std::cout << "NS3"; }
}

namespace  {  using namespace NS3;  }

void fun(Object b, int i)  {  int i1 = format(b);  }

int main()  {
    Object b;
    fun(b, 0);
}

1 ответ

  1. Давайте посмотрим на сообщение об ошибке, которое создает GCC:

    test.cpp: In function ‘void fun(NS1::Object, int)’:
    test.cpp:19:48: error: call of overloaded ‘format(NS1::Object&)’ is ambiguous
     void fun(Object b, int i)  {  int i1 = format(b);  }
                                                    ^
    test.cpp:19:48: note: candidates are:
    test.cpp:14:5: note: int NS3::format(const NS1::Object&)
     int format(const Object&) { std::cout << "NS3"; }
         ^
    test.cpp:5:5: note: int NS1::format(const NS1::Object&)
     int format(const Object&) { std::cout << "NS1"; }
         ^
    

    Неоднозначность возникает из-за поиска, зависящего от аргумента:

    Поиск, зависящий от аргумента, также известный как ADL или поиск Koenig,-это набор правил для поиска неполных имен функций в выражениях вызовов функций, включая неявные вызовы функций перегруженным операторам. Эти имена функций ищутся в пространствах имен их аргументов в дополнение к областям и пространствам имен, рассматриваемым обычным неполным поиском имен.

    В вашем случае вы пытаетесь вызвать format(b)where bis a NS1::Object.

    • Функция int NS3::format(const NS1::Object&)рассматривается, потому что вы вытащили в этом пространстве имен.
    • Функция int NS1::format(const NS1::Object&)рассматривается из-за ADL: параметр из пространства NS1имен , поэтому функция сопоставления из NS1будет рассматриваться также.
    • Обе функции имеют одну и ту же сигнатуру и поэтому неоднозначны.

    Стоит прочитать, что такое «Поиск, зависящий от аргумента» (он же ADL или «поиск Koenig»)? так же.