包装类的静态初始化列表

时间:2011-08-20 11:23:08

标签: c++ object-initializers

是否有可能在构造时以某种方式将静态初始化列表“传递”到容器包装类,而不是依次初始化其成员?

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的默认构造函数应 not 被调用。

1 个答案:

答案 0 :(得分: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,的技巧将所有项目合并为一个参数,其中IIRC与Boost.Assign类似。