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