Question: Is it possible to access a specific class from a header while hiding the other namespaces/classes defined in that header?
For example, say I have the header file -- outcome.hpp:
// outcome.hpp
namespace sports { namespace outcome {
class Injury {};
class Success {};
}}
In another header file -- api.hpp -- I wish to use sports::outcome::Injury
without having sports::outcome::Success
accessible to files that include api.hpp. Is that possible? If so, how can I achieve that?
P.S. In the actual code, api.hpp contains templated methods that would call methods of the Injury
class so a forward declaration is not sufficient.
My attempts:
In my ignorance, I tried to achieve this by placing the include
within an internal namespace. Here's a 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;
};
}
I celebrated prematurely when that worked:
// This cpp file compiles file \o/
#include "api.hpp"
int main(int argc, char *argv[]) {
sports::api::Boxing b;
// sports::outcome not accessible
}
How it fails:
Things fall apart if a container from the standard library is used as a class member in outcome.hpp. For example, using this version:
// outcome.hpp
#include <vector>
namespace sports { namespace outcome {
class Injury {
private:
std::vector x;
};
// ...
}}
Compilation fails with the following errors:
In file included from /usr/include/c++/4.6/ext/new_allocator.h:34:0, from /usr/include/c++/4.6/x86_64-linux-gnu/./bits/c++allocator.h:34, from /usr/include/c++/4.6/bits/allocator.h:48, from /usr/include/c++/4.6/vector:62, from outcome.hpp:1, from api.hpp:5, from main.cpp:1: /usr/include/c++/4.6/new:93:54: error: ‘void* sports::api::internal::operator new(sports::api::internal::std::size_t)’ may not be declared within a namespace /usr/include/c++/4.6/new:94:56: error: ‘void* sports::api::internal::operator new [](sports::api::internal::std::size_t)’ may not be declared within a namespace /usr/include/c++/4.6/new:95:35: error: ‘void sports::api::internal::operator delete(void*)’ may not be declared within a namespace /usr/include/c++/4.6/new:96:37: error: ‘void sports::api::internal::operator delete [](void*)’ may not be declared within a namespace /usr/include/c++/4.6/new:97:62: error: ‘void* sports::api::internal::operator new(sports::api::internal::std::size_t, const sports::api::internal::std::nothrow_t&)’ may not be declared within a namespace /usr/include/c++/4.6/new:98:64: error: ‘void* sports::api::internal::operator new [](sports::api::internal::std::size_t, const sports::api::internal::std::nothrow_t&)’ may not be declared within a namespace /usr/include/c++/4.6/new:99:58: error: ‘void sports::api::internal::operator delete(void*, const sports::api::internal::std::nothrow_t&)’ may not be declared within a namespace /usr/include/c++/4.6/new:100:60: error: ‘void sports::api::internal::operator delete [](void*, const sports::api::internal::std::nothrow_t&)’ may not be declared within a namespace /usr/include/c++/4.6/new:103:57: error: ‘void* sports::api::internal::operator new(sports::api::internal::std::size_t, void*)’ may not be declared within a namespace /usr/include/c++/4.6/new:104:59: error: ‘void* sports::api::internal::operator new [](sports::api::internal::std::size_t, void*)’ may not be declared within a namespace /usr/include/c++/4.6/new:107:52: error: ‘void sports::api::internal::operator delete(void*, void*)’ may not be declared within a namespace /usr/include/c++/4.6/new:108:52: error: ‘void sports::api::internal::operator delete [](void*, void*)’ may not be declared within a namespace
I'm obviously doing this wrong. Advice and a good telling off would be greatly appreciated.
sports::outcome::*
to be accessible in files that include api.hpp. - Shawn Chin