动态数组的初始化列表
Initializer list for dynamic arrays?
可以为静态数组的定义提供初始化列表。例子:
int main()
{
int int_static[2] = {1,2};
}
是否可以为动态数组提供类似的初始化列表?
int main()
{
int* int_ptr = new int[2];
}
这更接近我想做的:
struct foo
{
foo(){}
foo(void * ptr): ptr_(ptr) {}
void * ptr_;
};
int main()
{
foo* foo_ptr = new foo[10];
}
初始化时不应调用默认构造函数,而应调用foo:foo(void*)。
为动态数组提供静态初始化列表在加速器内核的实时编译中可能会很方便,因为加速器内核只有有限的堆栈可用,但同时你用(加速器编译时=主机运行时)静态初始化列表构造对象。
我认为不会(因为这将要求编译器生成额外的代码,即将参数的值复制到堆位置)。我认为c++0x支持其中的一些功能,但我不能使用它。现在我可以用这样一个构念。也许有人知道诀窍……
最好!
在OP发布这个问题的时候,c++ 11的支持可能还不是很普遍,这就是为什么公认的答案说这是不可能的。但是,现在所有主要的c++编译器都应该支持用显式初始化列表初始化动态数组。
语法new int[3] {1, 2, 3}
在c++ 11中被标准化。引用cppreference.com上的new expression页面:
new-expression创建的对象按照以下规则初始化:
…如果类型是数组类型,则初始化对象数组:
…如果初始化器是一个用大括号括起来的参数列表,则对数组进行聚合初始化。(因为c++ 11)
因此,根据OP的示例,在使用c++ 11或更新版本时,以下操作是完全合法的:
foo * foo_array = new foo[2] { nullptr, nullptr };
请注意,通过在初始化列表中提供指针,我们实际上是在引导编译器应用foo(void * ptr)
构造函数(而不是默认构造函数),这是期望的行为。
不,你不能那样做。
我认为c++不允许这样做,因为允许这样的事情并没有给语言增加任何的特性。换句话说,如果使用静态初始化器对动态数组进行初始化,那么动态数组的意义何在?
动态数组的要点是根据实际需要创建一个大小为N
的数组,该数组在运行时已知。也就是说,代码
int *p = new int[2];
对我来说没有以下内容有意义:
int *p = new int[N]; //N is known at runtime
如果是这样,那么您如何在静态初始化器中提供元素的数量,因为N
直到运行时才知道?
让我们假设你可以这样写:
int *p = new int[2] {10,20}; //pretend this!
但是你写这些有什么好处呢?什么都没有。它的几乎和
一样int a[] = {10,20};
真正的优点是当您被允许为N
元素的数组编写时。但问题是:
int *p = new int[N] {10,20, ... /*Oops, no idea how far we can go? N is not known!*/ };
不,您必须动态创建元素。
或者,您可以使用本地数组并将其元素复制到动态分配数组的元素上:
int main() {
int _detail[] = { 1, 2 };
int * ptr = new int[2];
std::copy( _detail, _detail+(sizeof detail / sizeof *detail), ptr );
delete [] ptr;
}
在将所有元素设置为0的限制版本中,您可以在new
调用中使用一对额外的括号:
int * ptr = new int[2](); // will value initialize all elements
但你似乎在寻找不同的东西。
考虑到您的实际类比int更复杂,并且由不同的值构造,它很复杂。如果已有一个数组/向量,并且有正确的默认值,则可以使用迭代器构造vector,或者必须使用位置new。
//vector
int main()
{
int int_static[2] = {1,2};
std::vector<int> int_dynamic(int_static, int_static+2);
//this is what everyone else is saying. For good reason.
}
//placement new
int function_that_returns_constructed_from_values() {
return rand();
}
int main()
{
int count = 2;
char *char_dynamic = new char[count * sizeof(int)];
int *int_dynamic = char_dynamic;
for(int i=0; i<count; ++i)
new(int_dynamic+i)int(function_that_returns_constructed_from_values());
//stuff
for(int i=0; i<count; ++i)
(int_dynamic+i)->~int(); //obviously not really int
delete []char_dynamic;
}
显然,vector是实现此目的的首选方法。
初始化器数据必须在某个地方。
。
#include <stddef.h>
#include <algorithm> // std::copy
#include <vector>
typedef ptrdiff_t Size;
template< class Type, Size n >
Size countOf( Type (&)[n] ) { return n; }
int main()
{
using namespace std;
static int const initData[] = {1,2};
static Size const n = countOf( initData );
// Initialization of a dynamically allocated array:
int* pArray = new int[n];
copy( initData, initData + n, pArray );
// Initialization of a vector:
vector<int> v( initData, initData + n );
}
EDIT:修正了上面代码中的一个想法。应要求,我赶紧加了一个例子。所以我写的错误地使用了std::copy
的返回值。
干杯,hth。
- 复制列表初始化的隐式转换的等级是多少
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 我使用向量来创建类对象列表.初始化向量时如何使用参数调用构造函数?
- C++11 中的混合列表初始化
- 我可以列表初始化 std::vector 并完美转发元素吗?
- 无法在声明时使用初始值设定项列表初始化常量字符*/字符串数组的向量
- C++20 从括号中的值列表初始化聚合,不支持内部数组
- 如何在向量列表初始化时避免对象复制以及如何延长临时的生存期
- 默认参数和空列表初始化
- 如何在列表初始化中放置额外的语句?
- C++列表初始化允许多个用户定义的转换
- 列表初始化是否将原子初始化为零
- 使用可变模板列表初始化数组,并放置new
- 使用整数初始化列表初始化长双精度的向量
- 直接列表初始化的自动规则
- 使用初始化列表初始化unique_ptr的容器,继续
- 如何修复"非聚合无法使用初始值设定项列表初始化" <map>
- 直接列表初始化和复制列表初始化之间的差异
- 为什么我可以在不使用赋值运算符的情况下使用列表初始化普通数组
- C++ - 使用类中的初始值设定项列表初始化动态集