c ++使用数组而不调用构造函数
c++ using an array without calling constructor
我的任务是在不调用 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'。
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]));
}
尝试
T *temp = (T*) malloc((end-begin) * sizeof(T));
如果您真的想手工完成,您正在寻找新的安置。首先你分配一个 "raw buffer" of unsigned char
s:
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
到 "emplace" 之类的东西写入内存 space。
问题是,在上面的例子中我完全忽略了对齐要求,这很危险。
因此,与其复制内存池和 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]);
}
大功告成。
正如其他人指出的那样,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
的开头,但忘记从 temp
的索引 0
开始。
但推荐的 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
,通常可以假定它在幕后使用这些优化。但是,如果由于某种原因无法或不需要重新构建应用程序,则此答案提供了重写所提供代码的有效有效方法。
我的任务是在不调用 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'。
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]));
}
尝试
T *temp = (T*) malloc((end-begin) * sizeof(T));
如果您真的想手工完成,您正在寻找新的安置。首先你分配一个 "raw buffer" of unsigned char
s:
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
到 "emplace" 之类的东西写入内存 space。
问题是,在上面的例子中我完全忽略了对齐要求,这很危险。
因此,与其复制内存池和 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]);
}
大功告成。
正如其他人指出的那样,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
的开头,但忘记从 temp
的索引 0
开始。
但推荐的 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
,通常可以假定它在幕后使用这些优化。但是,如果由于某种原因无法或不需要重新构建应用程序,则此答案提供了重写所提供代码的有效有效方法。