Initializer list for dynamic arrays?

后端 未结 5 1611
一个人的身影
一个人的身影 2020-11-30 14:44

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 s

相关标签:
5条回答
  • 2020-11-30 15:27

    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.

    The syntax new int[3] {1, 2, 3} was standardized in C++11. Quoting the new expression page on cppreference.com:

    The object created by a new-expression is initialized according to the following rules:
    ...
    If type is an array type, an array of objects is initialized:
    ...
    If initializer is a brace-enclosed list of arguments, the array is aggregate-initialized. (since C++11)

    So, given the OP's example, the following is perfectly legal when using C++11 or newer:

    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.

    0 讨论(0)
  • 2020-11-30 15:35

    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.

    //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.

    0 讨论(0)
  • 2020-11-30 15:37

    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.

    Cheers & hth.,

    0 讨论(0)
  • 2020-11-30 15:40

    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:

    int * ptr = new int[2]();  // will value initialize all elements
    

    But you seem to be looking for a different thing.

    0 讨论(0)
  • 2020-11-30 15:47

    No, you cannot do that.

    I think C++ doesn't allow this because allowing such thing doesn't add any nice-to-have feature to the language. In other words, what would be the point of dynamic array if you use a static initializer to initialize it?

    The point of dynamic array is to create an array of size N which is known at runtime, depending on the actual need. That is, the code

    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 static initializer because N isn't known until runtime?

    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 almost same 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:

     int *p = new int[N] {10,20, ... /*Oops, no idea how far we can go? N is not known!*/ };
    
    0 讨论(0)
提交回复
热议问题