在命名空间中包含实现文件以避免名称冲突
Include implementation file inside namespace to avoid name clashing
我正在围绕 C 库制作 C++ 包装器。假设库(我们称它为 Clib)定义了这样一个函数:
// clib.h
const char* clib_foo(clib_obj_t* obj);
在我的包装器中有以下内容:
// clibpp.h
#include <clib.h>
namespace clib {
std::string_view foo(const clib::obj_t& obj) {
return clib_foo(obj.raw());
};
}
// symbols from both clib.h and clibpp.h visible
现在,我的包装器只有 header。因此,当有人包含 clibpp.h
时,他们会看到来自 clibpp.h
和 clib.h
的符号。我想避免这种情况。我的想法是在 clibpp.h
header 的命名空间中包含 clib.h
header 以隐藏所有符号。
// clibpp.h
namespace clib {
namespace detail {
#include <clib.h>
}
std::string_view foo(const clib::obj_t& obj) {
return detail::clib_foo(obj.raw());
};
}
// symbols from only clibpp.h visible (apart from preprocessor definitions)
这是个好主意还是可行?为什么似乎没有人这样做?
Is this a good idea or possible to do?
不,这行不通,因为 C 库——出于明显的原因——没有在该命名空间内定义函数等。
Why doesn't anybody seem to do it?
因为不行。
如果您放弃拥有 header-only 包装器库的愿望,那么您可以避免“泄漏”C header 因为您只能将它包含在包装器库的翻译单元中.
请注意,这仍然不能解决名称冲突的所有问题,因为一个定义规则适用于跨翻译单元边界。如果您 link 使用 C 库,则该库的外部名称不能被其他任何东西使用。隐藏 C header 确实会阻止 macro-pollution.
我正在围绕 C 库制作 C++ 包装器。假设库(我们称它为 Clib)定义了这样一个函数:
// clib.h
const char* clib_foo(clib_obj_t* obj);
在我的包装器中有以下内容:
// clibpp.h
#include <clib.h>
namespace clib {
std::string_view foo(const clib::obj_t& obj) {
return clib_foo(obj.raw());
};
}
// symbols from both clib.h and clibpp.h visible
现在,我的包装器只有 header。因此,当有人包含 clibpp.h
时,他们会看到来自 clibpp.h
和 clib.h
的符号。我想避免这种情况。我的想法是在 clibpp.h
header 的命名空间中包含 clib.h
header 以隐藏所有符号。
// clibpp.h
namespace clib {
namespace detail {
#include <clib.h>
}
std::string_view foo(const clib::obj_t& obj) {
return detail::clib_foo(obj.raw());
};
}
// symbols from only clibpp.h visible (apart from preprocessor definitions)
这是个好主意还是可行?为什么似乎没有人这样做?
Is this a good idea or possible to do?
不,这行不通,因为 C 库——出于明显的原因——没有在该命名空间内定义函数等。
Why doesn't anybody seem to do it?
因为不行。
如果您放弃拥有 header-only 包装器库的愿望,那么您可以避免“泄漏”C header 因为您只能将它包含在包装器库的翻译单元中.
请注意,这仍然不能解决名称冲突的所有问题,因为一个定义规则适用于跨翻译单元边界。如果您 link 使用 C 库,则该库的外部名称不能被其他任何东西使用。隐藏 C header 确实会阻止 macro-pollution.