【问题标题】:static initializer list for wrapper class包装类的静态初始化列表
【发布时间】:2011-08-20 11:23:07
【问题描述】:

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

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

【问题讨论】:

  • C++0x 让这一切变得简单。不过我会尝试 C++98 的答案
  • 谢谢!抱歉,我不能使用 c++0x。
  • stackoverflow.com/questions/161790/… 他们在那里谈论一个 const 数组,但这是相同的潜在问题
  • 我认为你不能/不会通过使 store 成为指针数组来添加间接级别?
  • “很遗憾,我不能使用 STL 或 Boost。” - 为什么?这听起来很愚蠢。这就像使用 C# 并且无法使用 String 类。或者实际上是所有 .NET 框架。

标签: c++ object-initializers


【解决方案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 要求可能非常有限。

方法二:范围

如果您同意将您的类型 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 并至少对其余代码保持良好的隐藏。

方法三:运算符重载技巧

您还可以使用operator, 的技巧将所有项目减少为一个参数,这与Boost.Assign 所做的类似。

【讨论】:

  • 感谢艾伍德兰!不错的解决方案。不幸的是,两者都有相同的问题: T 的标准构造函数在包装类的构造时被调用。相反,应该调用一个带参数的构造函数,就像我在“b”的第一个定义的原始代码中一样。
  • 我认为如果没有新语法 (C++0x) 或从其他地方复制构造它们/分配它们是不可能的。
猜你喜欢
  • 2020-04-14
  • 1970-01-01
  • 2023-03-13
  • 2011-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-08
  • 1970-01-01
相关资源
最近更新 更多