この時点で、私はこれが私の問題の正しい解決策であることを心配していません(実際にはそうではありません)が、私はこの問題に巻き込まれ、それを解決できなかったので、それは私を悩ませていて、私はできません手放す。
PODタイプの汎用コンテナがあります。このコンテナは、メモリを初期化せず、パフォーマンス上の理由でコンストラクタやデストラクタを呼び出さないことでコピーを回避できます。これは、ユーザーに責任を負わせることと引き換えに行われます(ポッドやユースケースではそれほど大きな問題ではありません)。
これは、これを使用する方法についての非常に簡単なデモンストレーションです。
template <typename Pod_Type>
class PodContainer
{
public:
//stl-like iterators for compatibility with stl-algorithms
Pod_Type* begin();
Pod_Type* end();
//special "insertion" function that inserts a non-initialized pod
Pod_Type* new_empty();
//This "something" is my problem. I guess this has to be a functor.
//More on this later
Something generic_insert;
private:
Pod_Type* mStorage; //Allocated space for pods
};
//Simple structure to use as example
struct PodA
{
int x,y,z;
};
//Function to initialize a pod of type podA with the given params
inline
init_podA( podA* ptr, int a, int b, int c)
{
ptr->x = a; ptr->y = b; ptr->z = c;
}
int main()
{
//Create a buffer
PodContainer<podA> buff;
//Insert some elements and intialize them "by hand"
for (int i=0; i < 10 ; ++i)
{
init_podA( buff.new_empty(), 1,2,3);
}
}
コンテナクラスのすべてのメモリ管理の問題が解決され(私はすでにそれを広範囲にテストしました)、コンテナ自体が私の実際の問題に最適であることに注意してください。
さて、楽しい部分です。この「何か」がコンテナ内からinit_podA関数を呼び出すようにしたい。明らかに、これをBufferクラス内に配線することはできません。これは、ユーザーがポッドタイプに必要とする次のinit_xxx関数に必要なパラメーターの量さえわからないためです。2番目のパラメーターテンプレートをPodContainerクラスに渡すというアイデアを試し始めました。ここで、2番目は、実際の初期化関数への呼び出しをラップするファンクターを照会できるトレイトクラスです。PodContainerクラスでは、traitsクラスにクエリを実行し、そこで構築されるファンクターを保存して、ユーザーが呼び出し、メンバー関数であるかのような印象を与えることができます。
アイデアは、私がこの特性を次のように使用することでした:
template<typename PodType, typename PodTraits = MyPodTraits<PodType> >
class PodContainer
{
PodContainer():
generic_insert(PodTraits::get_inserter(this))
//The rest of the PodContainer definition
....
//And the user of the container would see this
PodContainer<PodA> buffer;
buffer.generic_insert(a,b,c); //Calls buffer->new_empty and initializes a pod
これも可能ですか?私はいくつかのブースト::バインドトリックを使用していると思います、私は正しいですか?コンテナに入れて受け取ることができるように、ファンクターのタイプは何ですか?より良いオプションはありますか?
ありがとう!!
編集:私はc++11を使用できないことに注意してください:(