c ++使用数组而不调用构造函数

时间:2017-03-28 09:49:14

标签: c++ arrays c++11 stdmove

我的任务是在不调用T(模板)构造函数的情况下创建模板类型数组。之后我想用std :: move从另一个数组移动一些值到这个数组。我怎么能用c ++做到这一点?这是我的代码:

void *temp = malloc((end-begin) * sizeof(T));
for (unsigned int i = begin; i < end; ++i){
    temp[i] = std::move(array[i]);
}

但这不起作用。编译器说如下:指向不完整类型'void'的指针的下标。

4 个答案:

答案 0 :(得分:2)

void数组毫无意义。 void是一种不完整的类型(并且没有大小),因此temp[i]会生成您正在查看的错误。

要实现您想要做的事情,为什么不使用std::vector,并在项目可用时将项目推送到其中?

std::vector<T> temp;
for (unsigned int i = begin; i < end; ++i){
    temp.push_back(std::move(array[i]));
}

答案 1 :(得分:1)

如果您真的想亲手操作,那么您正在寻找新的展示位置。首先,你分配一个&#34;原始缓冲区&#34; unsigned char s:

unsigned char* buf = new unsigned char(end-begin);

或:

auto buf = std::make_unique<unsigned char[]>(end-begin);

然后你会将new (buf) Tnew (buf+sizeof(T)) Tnew (buf+2*sizeof(T)) T等内容写入&#34; emplace&#34;你的对象进入那个记忆空间。

问题是,在上面的例子中,我完全忽略了对齐要求,这很危险。

因此,不要复制内存池和std::vector所做的内容,而只需使用std::vector

std::vector<T> vec;
vec.reserve(end-begin);
for (unsigned int i = begin; i < end; ++i){
   vec.push_back(std::move(array[i]);
}

你已经完成了。

答案 2 :(得分:0)

正如其他人指出void没有定义的大小,因此void*无法作为数组编入索引。

temp[1]从哪里开始?

天真的修复:

T *temp = std::malloc((end-begin) * sizeof(T));

与以下一起使用时同样糟糕:

temp[i] = std::move(array[i]);

该代码将调用赋值运算符,并且当处理temp[i]中的垃圾时,如果非平凡则会失败。例如,如果赋值明确地或隐式地在赋值目标中取消分配资源,它将在未初始化的temp[i]上运行并失败。

如果(IF!)你这样做了正确的代码:

std::memcpy(temp+i*sizeof(i),array[I],sizeof(T));

这行代码基本上假设T是一个简单的可复制类型。

第一行假设T的对象具有普通的默认构造函数。 如果T有一个普通的默认构造函数,那么大多数编译器都会优化元素初始化(这是我假设提问者试图避免的)。

所以推荐的代码(使用for循环)是:

T* temp= new T[end-being];
for(unsigned int i=begin;i<end;++i){
    temp[i-begin]=array[i];
}

注意:此代码还修复了在begin!=0时中断的原始代码中的错误。 该代码似乎是将一个子部分从array的中间复制到temp的开头,但忘记从0的索引temp开始。

但是这种复制的推荐C ++方法是:

T* temp= new T[end-being];
std::copy(array+begin,array+end,temp);

良好的实现将尽可能确定并利用任何批量内存操作。 因此,如果有效,这应该导致std::memmove(temp,array,(end-begin)*sizeof(T));

编译器可能无法识别的唯一最后一点是可能稍微提高效率

std::memcpy(temp,array,(end-begin)*sizeof(T));

在这种情况下实际上是有效的,因为我们知道temp不能与array重叠(更不用说要复制的范围了)。

脚注:正如评论中所指出的,最常规的C ++方法是使用std::vector,通常可以假设它在幕后使用这些优化。但是,如果由于某种原因重新构建应用程序是不可能或不可取的,那么这个答案提供了重写所提供代码的有效方法。

答案 3 :(得分:-1)

尝试

T *temp = (T*) malloc((end-begin) * sizeof(T));