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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:29:19  来源:igfitidea点击:

Initializer list for dynamic arrays?

c++arraysdynamic

提问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 Nwhich 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 Nisn'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 Nelements. 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 newcall:

在将所有元素设置为 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.,