Определение функции в пространстве имен, отличном от ADL, "локального" или глобального пространства имен

Смотрите код ниже:

#include <iostream>

/// Definition of void perform(a_lib::a_class&). Where should I put this definition?
/// See the comments below for where I've tried placing it.
// void perform(a_lib::a_class&) {
//   std::cout << "performing on a_lib::a_class" << std::endl;
// }

namespace a_lib {
  class a_class {  };

  // WORKS HERE but it pollutes a_lib (namespace of third-party library).
}

namespace mine {
  // DOESN'T WORK HERE: "use of undeclared identifier 'perform'".
}

// WORKS HERE but it pollutes the global namespace.

namespace b_lib {
  // WORKS HERE but it pollutes b_lib (namespace of third-party library).

  template <typename Type>
  void b_func(Type& obj) {
    perform(obj);
  }
}

namespace mine {
  // DOESN'T WORK HERE: "use of undeclared identifier 'perform'".

  void run() {
    a_lib::a_class a_obj;
    b_lib::b_func(a_obj);
  }
}

int main(int, char**) {
  mine::run();

  return 0;
}

a_lib а также b_lib являются пространствами имен, принадлежащими двум различным сторонним библиотекам. mine это мое собственное пространство имен.

Меня учили, что плохая идея - загрязнять глобальное пространство имен, и в этом вопросе они также говорят, что добавление типов в std плохая идея Я думаю, что последнее верно для пространств имен в целом; Вы не должны добавлять типы в пространство имен, которое не принадлежит вам.

Но как бы я решил проблему выше, не нарушая эти принципы? Где я должен поставить определение perform() и как я могу получить b_func() называть это?

Контекст: я пытаюсь добавить внешний злак serialize() для типа SFML в собственном пространстве имен. Это здесь приведенный пример.

1 ответ

Вам необходимо определить, где компилятор при обработке "b_func" может найти "выполнить".

namespace mine {
  // DOESN'T WORK HERE: "use of undeclared identifier 'perform'".

  // dom -  yes it will, but there is 'more' to the name than your example shows

  void perform(Type& obj) { /* do something with obj */}

}

// WORKS HERE but it pollutes the global namespace.

namespace b_lib {
  // WORKS HERE but it pollutes b_lib (namespace of third-party library).

  // dom -  use here is easy with correct and 'more-complete' name:

  template <typename Type>
  void b_func(Type& obj) {  mine::perform(obj); }
  // -----------------------^^^^^^^^^^^^^^^^^^^ --- more to name
}

Поскольку "mine" - это пространство имен, более полное имя может "охватывать" пространства имен.

Обратите внимание, что в реализации mine:: execute () также должно быть определено "Type" для использования объекта obj.

Другие вопросы по тегам