den Code Siehe unten:eine Funktion in einem anderen Namensraum als die ADL definieren, „local“ oder globalen Namensraum
#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
und b_lib
sind Namespaces zwei Bibliotheken verschiedener Drittanbieter gehören. mine
ist mein eigener Namensraum.
Ich habe gelernt, dass es eine schlechte Idee ist, den globalen Namensraum zu verschmutzen und in this question sie auch sagen, dass das Hinzufügen von Typen zu std
eine schlechte Idee ist. Ich denke, Letzteres gilt für Namespaces im Allgemeinen; Sie sollten keine Typen zu einem Namespace hinzufügen, der nicht Ihnen gehört.
Aber wie ich werde ich das Problem lösen, oben ohne diese Prinzipien zu brechen? Wo sollte ich die Definition perform()
setzen und wie bekomme ich b_func()
, um es zu nennen?
Kontext: Ich versuche, einen externen cereal serialize() für einen SFML Typ in meinem eigenen Namespace hinzuzufügen. Dies ist ein reduziertes Beispiel.
Um die Schnittstelle von 'a_lib erweitern :: a_class' Sie die Dinge auf diese Art Namensraum hinzufügen sollten. Ob es eine gute Idee ist, die Schnittstelle von Typen zu erweitern, die Sie nicht besitzen (z. B. indem Sie sie serialisierbar machen), ist die Schlüsselfrage, aber wenn Sie das tun, sollten Sie dies im Namespace des Typs tun. Eine weitere Möglichkeit besteht darin, in Ihrem eigenen Namespace einen eigenen Typ zu definieren, der von 'a_class' abgeleitet ist, und die Serialisierungsunterstützung in Ihrem Namespace hinzuzufügen. –
* "Ob es eine gute Idee ist, die Schnittstelle von Typen zu erweitern, die Sie nicht besitzen (z. B. durch Serialisierung), ist die Schlüsselfrage" * Das ist ein wirklich guter Punkt. Ich werde stattdessen von 'a_class' abgeleitet. Vielen Dank. – haisareisa