问题:是否可以在隐藏该标头中定义的其他名称空间/类的同时从标头访问特定类?
例如,假设我有头文件 --结果.hpp:
// outcome.hpp
namespace sports { namespace outcome {
class Injury {};
class Success {};
}}
在另一个头文件 - api.hpp - 我希望在sports::outcome::Injury
无法sports::outcome::Success
访问包含api.hpp的文件的情况下使用。那可能吗?如果是这样,我该如何实现?
PS 在实际代码中,api.hpp包含将调用Injury
类方法的模板化方法,因此前向声明是不够的。
我的尝试:
在我的无知中,我试图通过将 放置include
在内部命名空间中来实现这一点。这是一个SSCCE:
// api.hpp
namespace sports { namespace api {
namespace internal {
#include "outcome.hpp" // I'm trying to hide symbols within this header
using sports::outcome::Injury;
}
class Boxing {
private:
internal::Injury sustained;
};
}
当它奏效时,我过早地庆祝:
// This cpp file compiles file \o/
#include "api.hpp"
int main(int argc, char *argv[]) {
sports::api::Boxing b;
// sports::outcome not accessible
}
它是如何失败的:
如果将标准库中的容器用作result.hpp中的类成员,事情就会崩溃。例如,使用这个版本:
// outcome.hpp
#include <vector>
namespace sports { namespace outcome {
class Injury {
private:
std::vector x;
};
// ...
}}
编译失败并出现以下错误:
在 /usr/include/c++/4.6/ext/new_allocator.h:34:0 包含的文件中, 来自 /usr/include/c++/4.6/x86_64-linux-gnu/./bits/c++allocator.h:34, 来自 /usr/include/c++/4.6/bits/allocator.h:48, 来自 /usr/include/c++/4.6/vector:62, 从结果.hpp:1, 来自 api.hpp:5, 来自 main.cpp:1: /usr/include/c++/4.6/new:93:54: 错误:'void* sports::api::internal::operator new(sports::api::internal::std::size_t)' 可能不是在命名空间中声明 /usr/include/c++/4.6/new:94:56: 错误:'void* sports::api::internal::operator new [](sports::api::internal::std::size_t)' 可能不在命名空间内声明 /usr/include/c++/4.6/new:95:35: 错误:'void sports::api::internal::operator delete(void*)' 不能在命名空间中声明 /usr/include/c++/4.6/new:96:37: 错误:'void sports::api::internal::operator delete [](void*)' 不能在命名空间中声明 /usr/include/c++/4.6/new:97:62: 错误: 'void* sports::api::internal::operator new(sports::api::internal::std::size_t, const sports:: api::internal::std::nothrow_t&)' 不能在命名空间中声明 /usr/include/c++/4.6/new:98:64: 错误:'void* sports::api::internal::operator new [](sports::api::internal::std::size_t, const sports ::api::internal::std::nothrow_t&)' 不能在命名空间中声明 /usr/include/c++/4.6/new:99:58: 错误:'void sports::api::internal::operator delete(void*, const sports::api::internal::std::nothrow_t&)'不能在命名空间中声明 /usr/include/c++/4.6/new:100:60: 错误:'void sports::api::internal::operator delete [](void*, const sports::api::internal::std::nothrow_t& )' 不能在命名空间中声明 /usr/include/c++/4.6/new:103:57: 错误:'void* sports::api::internal::operator new(sports::api::internal::std::size_t, void*)'不能在命名空间中声明 /usr/include/c++/4.6/new:104:59: 错误:'void* sports::api::internal::operator new [](sports::api::internal::std::size_t, void* )' 不能在命名空间中声明 /usr/include/c++/4.6/new:107:52: 错误:'void sports::api::internal::operator delete(void*, void*)' 不能在命名空间中声明 /usr/include/c++/4.6/new:108:52: 错误:'void sports::api::internal::operator delete [](void*, void*)' 不能在命名空间中声明
我显然做错了。建议和良好的告白将不胜感激。