【发布时间】:2016-04-04 11:44:22
【问题描述】:
请看下面的代码:
#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 是我自己的命名空间。
我被告知污染全局命名空间是个坏主意,在this question 中,他们还说向std 添加类型是个坏主意。我认为后者通常适用于名称空间。您不应该将类型添加到不属于您的命名空间。
但是我如何在不违反这些原则的情况下解决上述问题呢?我应该把perform()的定义放在哪里,如何让b_func()调用它?
上下文:我正在尝试在我自己的命名空间中为 SFML 类型添加外部 cereal serialize()。这是一个简化的例子。
【问题讨论】:
-
要扩展
a_lib::a_class的接口,您应该将内容添加到该类型的命名空间。扩展您不拥有的类型的接口是否是一个好主意(例如,通过使它们可序列化)是关键问题,但如果您要这样做,那么您应该在类型的命名空间中进行。另一种选择是在您自己的命名空间中定义您自己的派生自a_class的类型,并在您的命名空间中添加序列化支持。 -
“扩展你不拥有的类型的接口是否是一个好主意(例如,通过使它们可序列化)是关键问题” 这是一个非常好的观点。我将从
a_class派生。谢谢。
标签: c++ namespaces argument-dependent-lookup