C++ 动态数组的初始化列表?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7124899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Initializer list for dynamic arrays?
提问by ritter
It is possible to give an initializer list to the definition of a static array. Example:
可以为静态数组的定义提供初始化列表。例子:
int main()
{
int int_static[2] = {1,2};
}
Is a similar initializer list possible for a dynamic array?
动态数组是否可以使用类似的初始化列表?
int main()
{
int* int_ptr = new int[2];
}
This is closer to what I am trying to do:
这更接近我想要做的事情:
struct foo
{
foo(){}
foo(void * ptr): ptr_(ptr) {}
void * ptr_;
};
int main()
{
foo* foo_ptr = new foo[10];
}
At initialization time not the default constructor should be called, but foo:foo(void*).
在初始化时,不应调用默认构造函数,而是调用 foo:foo(void*)。
The point of having a static initializer list for a dynamic array might come handy in the case of Just-In-Time compilation for accelerator cores which do have only a limited amount of stack available, but at the same time you construct your objects with a (accelerator compile time = host run time) static initializer list.
在实时编译加速器内核的情况下,动态数组的静态初始化列表可能会派上用场,这些内核的可用堆栈数量有限,但同时您使用(加速器编译时间 = 主机运行时间)静态初始化列表。
I assume not (since this would require the compiler to generate additional code, namely to copy the values of the arguments to the heap location). I think c++0x supports some of this, but I cannot use it. Right now I could use such a construct. Maybe someone knows a trick..
我假设不是(因为这需要编译器生成额外的代码,即将参数的值复制到堆位置)。我认为 c++0x 支持其中的一些,但我不能使用它。现在我可以使用这样的构造。也许有人知道一个技巧..
Best!
最好的事物!
采纳答案by Nawaz
No, you cannot do that.
不,你不能那样做。
I think C++ doesn't allow this because allowing such thing doesn't add any nice-to-havefeature to the language. In other words, what would be the point of dynamicarray if you use a staticinitializer to initialize it?
我认为 C++ 不允许这样做,因为允许这样的事情不会为语言添加任何好的特性。换句话说,如果您使用静态初始化程序来初始化动态数组,那么它的意义何在?
The point of dynamic array is to create an array of size N
which is knownat runtime, depending on the actual need. That is, the code
动态阵列的点是创建大小的数组N
,其已知在运行时,根据实际的需要。也就是说,代码
int *p = new int[2];
makes less sense to me than the following:
对我来说比以下更没有意义:
int *p = new int[N]; //N is known at runtime
If that is so, then how can you provide the number of elements in the staticinitializer because N
isn't known until runtime?
如果是这样,那么您如何在静态初始值设定项中提供元素数量,因为N
直到运行时才知道?
Lets assume that you're allowed to write this:
让我们假设你被允许写这个:
int *p = new int[2] {10,20}; //pretend this!
But what big advantage are you getting by writing this? Nothing. Its almostsame as:
但是你写这篇文章有什么好处呢?没有。它几乎与以下相同:
int a[] = {10,20};
The real advantage would be when you're allowed to write that for arrays of N
elements. But then the problem is this:
真正的优势是当您被允许为N
元素数组编写它时。但问题是这样的:
int *p = new int[N] {10,20, ... /*Oops, no idea how far we can go? N is not known!*/ };
回答by DaoWen
At the time the OP posted this question, C++11 support may not have been very prevalent yet, which is why the accepted answer says this is not possible. However, initializing a dynamic array with an explicit initializer list should now be supported in all major C++ compilers.
在 OP 发布这个问题时,C++11 支持可能还不是很普遍,这就是为什么接受的答案说这是不可能的。但是,现在所有主要的 C++ 编译器都应该支持使用显式初始化列表初始化动态数组。
The syntax new int[3] {1, 2, 3}
was standardized in C++11. Quoting the new expressionpage on cppreference.com:
语法new int[3] {1, 2, 3}
在 C++11 中标准化。引用cppreference.com 上的新表达式页面:
The object created by a new-expression is initialized according to the following rules:
...
If typeis an array type, an array of objects is initialized:
...
If initializeris a brace-enclosed list of arguments, the array is aggregate-initialized. (since C++11)
由 new 表达式创建的对象根据以下规则进行初始化:
...
如果type是数组类型,则初始化对象数组:
...
如果初始化程序是括号括起来的参数列表,则该数组是聚合初始化。(C++11 起)
So, given the OP's example, the following is perfectly legal when using C++11 or newer:
因此,鉴于 OP 的示例,使用 C++11 或更高版本时,以下内容是完全合法的:
foo * foo_array = new foo[2] { nullptr, nullptr };
Note that by providing pointers in the initializer list, we're actually coaxing the compiler to apply the foo(void * ptr)
constructor (rather than the default constructor), which was the desired behavior.
请注意,通过在初始化列表中提供指针,我们实际上是在诱使编译器应用foo(void * ptr)
构造函数(而不是默认构造函数),这是我们想要的行为。
回答by David Rodríguez - dribeas
No, you will have to create the elements dynamically.
不,您必须动态创建元素。
Alternatively, you can use a local array and copy its elements over those of the dynamically allocated array:
或者,您可以使用本地数组并将其元素复制到动态分配的数组的元素上:
int main() {
int _detail[] = { 1, 2 };
int * ptr = new int[2];
std::copy( _detail, _detail+(sizeof detail / sizeof *detail), ptr );
delete [] ptr;
}
In the limited version of setting all elements to 0, you can use an extra pair of parenthesis in the new
call:
在将所有元素设置为 0 的限制版本中,您可以在new
调用中使用额外的一对括号:
int * ptr = new int[2](); // will value initialize all elements
But you seem to be looking for a different thing.
但你似乎在寻找不同的东西。
回答by Mooing Duck
Given that you're real class is more complex than an int, and constructed from differing values, it's complicated. A vector can be constructed with iterators if you have an existing array/vector with the correct values to default from, or you have to use placement new.
鉴于您是真正的类比 int 更复杂,并且由不同的值构成,它很复杂。如果您有一个具有正确默认值的现有数组/向量,或者您必须使用新的布局,则可以使用迭代器构建向量。
//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;
}
Obviously, the vector is the preferred way to do this.
显然,向量是执行此操作的首选方法。
回答by Cheers and hth. - Alf
The initializer data must be somewhere anyway. Simply name it.
无论如何,初始化程序数据必须在某处。简单地命名它。
E.g.,
例如,
#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: fixed a thinko in above code. I hastened to add example on request. So what I put did erroneously use return value from std::copy
.
编辑:在上面的代码中修复了一个 thinko。我赶紧根据要求添加示例。所以我放的东西错误地使用了来自std::copy
.
Cheers & hth.,
干杯 & hth.,