How can I assign an array from an initializer list?
Asked Answered
L

3

23

I have a limited knowledge about c++. I tried to compile a c++ library and when I run the make file for the following header file

mcmc_dhs.h

#include <algorithm>
#include <map>

// intrinsic shape and (reduced) shear just add?
//#define WLNOISE

// use shear instead of reduced shear for model
//#define NOREDSHEAR

/// parameters for the M200-concentration relation
const number mcreal[2] = {9.59,-0.102}; // Dolag et al. (2004)
//const number mcreal[2] = {5.26,-0.100}; // Neto et al. (2007) [Millenium Run]

/// critical density at z=0 (h100=1) in [Msun/Mpc^3]
const number rhocrit = exp(log(rhoCrit)+3.*log(Mpc)-log(Msun)); 

/// two extra halo parameters: r200 (and concentration: 2)
#define PARAMS 1

/// define region (square; twice value here) about halo that considers sources for model
#define REGION 10.0*arcmin

class mcmc_dhs : public mcmc
{
 public:

  mcmc_dhs() : 
  data(), cosmohandler(0.3,0.7,0.21,0.8,0.04),
    lenseff(), intrvar()
    {
      boundaries = 
    {{0,512},{0,512},{0.01,5.},{100.,3000.},{0.1,50}};
    }
  ~mcmc_dhs() {}

  /// size of grid for looking up sources
  static const int Ngrid = 200;

It returns the following error message:

mcmc_dhs.h:55:67: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
      boundaries = {{0,512},{0,512},{0.01,5.},{100.,3000.},{0.1,50}};
                                                                   ^
mcmc_dhs.h:55:17: error: assigning to an array from an initializer list
      boundaries = {{0,512},{0,512},{0.01,5.},{100.,3000.},{0.1,50}};
                 ^
In file included from ../modules/matrix.h:15:0,
                 from ../modules/probdensity.h:4,
                 from ../modules/mcmc.h:4,
                 from mcmc_dhs.h:4,
Larynx answered 11/5, 2015 at 22:47 Comment(6)
Sounds like your compiler isn't in C++11 compatibility mode (or doesn't support it)? What compiler are you using?Ly
possible duplicate of Error: Assigning to an array from an initializer listAustere
Well, it says, that you have to use the -std=c++11 flag. So why don't you?Adessive
@Adessive the error per se it's not because of lack of support for c++11. Even with -std=c++11, you'll still get the same error (not the warning though). You get a warning even in C++98 code, since modern g++ compilers (>=4.9) interpret the braces as a std::initializer_list (even if you don't compile with -std=c++11) They consider this as an extension, and it is enabled by default (see the warning message).Asher
@vsoftco: You are right of course - I should have had a closer look at the code first. But I'd still would recommend using the c++11 flag if possible.Adessive
@Adessive that's indeed a good point, as some C++11 are not implement as extensions, and if the code uses them, it won't compile without -std=c++11.Asher
A
27

You cannot assign directly to an array after its declaration. Basically your code is the same as

int main()
{
    double arr[2][2];
    arr = { {1, 2}, {3, 4.5} }; // error
}

You have to either assign the value at declaration

double arr[2][2] = { {1, 2}, {3, 4.5} };

or use a loop (or std::copy) to assign elements. Since your array seems to be a member variable, you can also initialize it in the constructor initialization list:

 mcmc_dhs() : data(), cosmohandler(0.3,0.7,0.21,0.8,0.04), 
              lenseff(), intrvar(), 
              boundaries{{0,512},{0,512},{0.01,5.},{100.,3000.},{0.1,50}}
 { 
    // rest of ctor implementation
 }
Asher answered 11/5, 2015 at 22:51 Comment(0)
K
2

When you said

boundaries = 
{{0,512},{0,512},{0.01,5.},{100.,3000.},{0.1,50}};

it was incorrect, because C++ does not let you reassign array values. There is an easy workaround, but it is somewhat tedious. All you have to do is assign the values one by one.

For example:

boundaries[0][0] = 0;
boundaries[0][1] = 512;
boundaries[1][0] = 0;
boundaries[1][1] = 512;

and so on. I had this same problem in an Arduino program.

Klaxon answered 20/2, 2020 at 19:11 Comment(0)
G
0

Array are essentially just pointers. C++ (being a symbol based programming language) has its own interpretations for arrays. Meaning:

int* a[3]; you've declared the array, but currently the values assigned to each element is some junk values that were already stored at the memory location allotted to your array.

a={1,2,3}; won't work because: C++ treat the array name 'a' as a pointer pointing at the address location of the 1st element in array. 'a' is basically interpreted by C++ as '&a[0]' which is the address of the element a[0]

So, you have 2 ways to go about assigning values

  1. using array indexing (your only option if you don't know what pointers are)

    int a[3]; for(int i=0;i<3;++i) // using for loop to assign every element a value { cin>>a[i]; }

2 treating it as a pointer and using pointer operation

    int a[3];
    for(int i=0;i<3;++i) // using for loop to assign every element a value
    {
    cin>>*(a+i); // store value to whatever it points at starting at (a+0) upto (a+2)
    }

Note: can't use ++a pointer operation as ++ changes the position of a pointer whereas a+i will not change the location of pointer 'a', and anyways using ++ will give a compiler error.

Recommend reading Stephen Davis C++ for dummies book.

Giuseppinagiustina answered 29/6, 2020 at 9:56 Comment(1)
Arrays are not pointers, they are types in their own right, e.g. sizeof(int[2][2]) equals 4 * sizeof(int), not sizeof(int*) or 2 * sizeof(int*). An array can be assigned to a pointer of the appropriate type, but they are distinct types (and I view this assignment behaviour as a defect in C and C++).Gaylord

© 2022 - 2024 — McMap. All rights reserved.