1

我的任务是创建一个模板类型数组而不调用 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

4 回答 4

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]));
}
于 2017-03-28T09:58:07.933 回答
1

如果您真的想手工完成,您正在寻找放置 new。首先你分配一个unsigned chars 的“原始缓冲区”:

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

或者:

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

然后您编写诸如new (buf) T, new (buf+sizeof(T)) T,之类的东西new (buf+2*sizeof(T)) T来将您的对象“放置”到该内存空间中。

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

因此,不要复制内存池和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]);
}

你就完成了。

于 2017-03-28T10:03:17.163 回答
0

正如其他人指出的那样void,没有定义的大小,因此void*不能作为数组进行索引。

从哪里temp[1]开始?

一个天真的修复:

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

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

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

该代码将调用赋值运算符,并且在对temp[i]. 例如,如果分配显式或隐式取消分配目标中的资源,它将对未初始化的资源进行操作temp[i]并失败。

如果(如果!)您这样做了,那么正确的代码将是:

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通常可以假定在幕后使用这些优化的方法。但是,如果由于某种原因无法或不希望重新构建应用程序,则此答案提供了重写所提供代码的有效有效方法。

于 2017-03-28T10:27:21.177 回答
-1

尝试

T *temp = (T*) malloc((end-begin) * sizeof(T));
于 2017-03-28T10:00:00.980 回答