私は と をよく知って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 long
BOM に基づいてファイルを開きます。basic_filebuf
ラッパーは、クライアントが選択したものであるテンプレート パラメーターからも派生します。内部的には、Unicode コード ポイントをファイルからクライアントが希望するエンコーディングに変換します。内部を格納するときに問題が発生しbasic_filebuf
ます。これは、テンプレート パラメーターとして任意の型で宣言できるためです。basic_filebuf
クライアントが独自のインスタンスを渡せるようにしたいので、テンプレートの特殊化を使用したくありません。
C++11 の機能が制限されている VS2010 と互換性がある必要があります。