私は と をよく知ってboost::anyいboost::variantますが、この場合、それらは私のニーズに合いません。
通常、不明なタイプのオブジェクトを含めるには、共通ベースから派生させ、仮想メソッドを介してインスタンスにアクセスします。しかし、共通のベースを使用することが不可能な場合はどうすればよいでしょうか?
この例では、含まれている型を知る必要があることはわかっていますが、ご容赦ください。std::vectorトップレベルクラスもテンプレートであるテンプレートクラスです。私の知る限り、STL ヘッダーを変更せずに非テンプレート ベースを指定することはできません。ここで、単一の型のベクトルを作成したいとしますが、それを含むクラスはその型を気にしませんが、いくつかの「共通」メソッドへのアクセスを必要とsize()しpop_back()ます。
を使用するboost::anyと、型が消去され、含まれているオブジェクトを逆参照することがほとんど不可能になります。boost::variantまた、tuple挿入される可能性のある型を事前に知っておく必要があり、それを含むクラス自体がテンプレートになります。
私がこれまでに持っているものは次のようなものです:
struct container
{
virtual ~container() = 0;
virtual void pop_back() = 0;
virtual size_t size() = 0;
...
}
template < typename T >
struct contained
{
std::vector< T > _vec;
contained ( size_t n, T _what ) : _vec( n, _what ) {}
virtual void pop_back() { _vec.pop_back(); }
...
}
class some_class
{
container* _cont;
template < typename T >
void create ( T _first ) { _cont = new contained< T >(1,_first); }
...
}
ここでクライアントが呼び出すことができcreate()、テンプレート パラメータは自動的に決定されます。私が知っている良い例ではありませんが、クライアントからテンプレート パラメーターを隠そうとしています。これを行わないsome_classと、保存されているタイプも追跡する必要があります。
私のメソッドは、特に内部クラスに独自の仮想メソッドがある場合に、パフォーマンスの低下を引き起こす仮想呼び出しに依存しています。
私のニーズにより適した他のタイプのコンテナはありますか?
理想的には、私はこのようなものが欲しい
container = std::vector< T >;
container.pop_back();
container.push_back( T2 ); // compile error if types don't match
仮想メソッドに依存するのではなく、内部的に型を追跡し、単純なキャストを行う場所。違いautoは、一度宣言すると型が変わる可能性があるということです。
編集:
実際には、ラッパーを作成したいと思いますstd::basic_filebuf。charこのラッパー クラスは、wchar_tまたはunsigned longBOM に基づいてファイルを開きます。basic_filebufラッパーは、クライアントが選択したものであるテンプレート パラメーターからも派生します。内部的には、Unicode コード ポイントをファイルからクライアントが希望するエンコーディングに変換します。内部を格納するときに問題が発生しbasic_filebufます。これは、テンプレート パラメーターとして任意の型で宣言できるためです。basic_filebufクライアントが独自のインスタンスを渡せるようにしたいので、テンプレートの特殊化を使用したくありません。
C++11 の機能が制限されている VS2010 と互換性がある必要があります。