Определение функции в пространстве имен, отличном от 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.