使用相邻元素的非数组布局创建数组吗?

时间:2017-12-05 09:58:07

标签: c++ language-lawyer

我想创建一个模板函数,它可以初始化(使用placement new)一个数组,对于每个元素,调用lambda来初始化它。

template <typename OBJECT, typename LAMBDA>
void initialize(void *storage, int size, LAMBDA lambda) {
    for (int i=0; i<size; i++) {
        lambda(static_cast<char*>(storage)+i*sizeof(OBJECT), i);
    }
}

实际的lambda可能是这个(例如,一个整数数组,其中每个元素都被初始化为其索引):

[](void *storage, int index){ new(storage) int(index); }

这很有效。但是,正如我所看到的,它并没有创建一个实际的数组,因为我没有使用placement-new-array,而是对每个元素进行单独的placement-new调用,即使内存布局应该是相同的。我对吗?我可以将此内存称为数组吗? 如果没有,可以通过某种方式实现此功能吗?

(基本上,如果std::vector有一个数组生成器push_array_back函数,该函数具有sizelambda参数,则此功能是相同的。它会{ {1}} push_back的元素,初始化为值size给出)

1 个答案:

答案 0 :(得分:0)

  

我是对的吗?我可以将此内存称为数组吗?如果没有,这个功能可以以某种方式实现吗?

这基本上与std::vectordata()的基本问题相同,并在CWG 2182中指出。它将这个内存称为数组是未定义的行为,但实际上它需要工作,因为很多代码都依赖于它的工作。没有办法实现它。

侧节点,不要调用您的callables lambda。他们不必是lambdas。并且让语言帮助您指针偏移:

auto p = static_cast<Object*>(storage);
for (int i = 0; i < size; ++i) {
    construct(static_cast<void*>(p + i), i);
}