質問: ヘッダーで定義されている他の名前空間/クラスを非表示にしながら、ヘッダーから特定のクラスにアクセスすることは可能ですか?
たとえば、ヘッダー ファイルoutput.hppがあるとします。
// outcome.hpp
namespace sports { namespace outcome {
class Injury {};
class Success {};
}}
別のヘッダー ファイル ( api.hpp ) では、 api.hppを含むファイルにアクセスsports::outcome::Injury
せずに使用したいと考えています。それは可能ですか?もしそうなら、どうすればそれを達成できますか?sports::outcome::Success
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
}
失敗する方法:
標準ライブラリのコンテナーがoutput.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 から、 output.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*)' は名前空間内で宣言されていない可能性があります
私は明らかにこれを間違っています。アドバイスと良い報告をいただければ幸いです。