2

構築時に静的初期化子リストをコンテナラッパークラスに「渡す」ことは可能ですか?それは次にそのメンバーを初期化しますか?

struct bar {
  bar(void * ptr): ptr(ptr) {}
  void * ptr;
};

template<class T, int N>
struct foo
{
  foo( args ) :store(args)  {}  // here the arg list should be passed

  T store[N];
};

int main()
{
  bar b[2]={NULL,NULL};
  foo<bar,2> f(NULL,NULL); // This should be possible
}

残念ながら、STLやBoostは使用できません。

これの有用性に疑問がある場合は、説明させてください。まず、これは非常に「調理された」セットアップです。セットアップ全体を説明することは、ここに投稿するのに十分ではなく、役に立ちません。ネストされた式テンプレートツリーがある場合を想像してみてください。コンパイル時にそれをトラバースし、関連するオブジェクトを収集して、上記のようなコンテナラッパーに格納します。ご不明な点がございましたらお問い合わせください。

編集済み:Tのデフォルトコンストラクターは呼び出さないでください。

4

1 に答える 1

2

方法1:va_args

バーPODを作成することに同意する場合、これは次の方法で実行できますva_args

#include <stdarg.h>

struct bar {
  void * ptr;
};

template<class T, int N>
struct foo
{
  foo(...)  { // here the arg list should be passed
    va_list ap;
    va_start(ap, N);

    for (int i = 0; i < N; ++i) {
      store[i] = va_arg(ap, T);
    }
    va_end(ap);
  }

  T store[N];
};

int main()
{
  foo<bar,2> f(bar(),bar());
}

しかし、それは素晴らしいことではありません-あなたは私の好みのために発信者を少し信頼しすぎる必要があり、POD要件はかなり制限される可能性があります。

方法2:範囲

タイプをデフォルトの構築可能と割り当て可能の両方にすることに同意する場合は、次のT方法を使用できます。

#include <assert.h>
#include <stdlib.h>

struct bar {
  bar(void * ptr): ptr(ptr) {}
  bar() {}
  void * ptr;
};

template<class T, int N>
struct foo
{
  foo(T *begin, const T *end)  { // here the arg list should be passed
    // Normally I'd use std::copy here!
    int i = 0;
    while (begin != end) {
       assert(i < N);
       store[i] = *begin++;
    }
  }

  T store[N];
};

int main()
{
  bar b[2]={NULL,NULL};
  foo<bar,2> f(&b[0], &b[sizeof(b)/sizeof(bar)]);
}

完全にシームレスではありません。最終的には配列とオブジェクトのインスタンスの両方になりますが、配列static constを作成して、少なくとも残りのコードから十分に隠しておくことができます。

方法3:演算子のオーバーロードのトリック

トリックを使用しoperator,て、すべてのアイテムを1つのパラメーターに減らすこともできます。これは、IIRCがBoost.Assignの機能と似てます。

于 2011-08-20T11:46:16.760 に答える