如何使用初始化列表分配一个数组?

23

我对C++的知识有限。我试图编译一个C++库,并在运行以下头文件的make文件时:

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;

它会返回以下错误信息:

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,

听起来你的编译器没有处于C++11兼容模式(或者不支持它)?你使用的是哪个编译器? - Michael Dorgan
可能是重复的问题:错误:从初始化列表分配到数组 - m.s.
好的,它说你必须使用-std=c++11标志。那你为什么不用呢? - MikeMB
@MikeMB,错误本身并不是由于缺乏对c++11的支持。即使使用-std=c++11,您仍将获得相同的错误(尽管没有警告)。即使在C++98代码中,由于现代g ++编译器(> = 4.9)将大括号解释为std :: initializer_list(即使您不使用-std=c++11编译),您也会收到警告。他们认为这是一种扩展,并且默认情况下启用(请参见警告消息)。 - vsoftco
@vsoftco:当然,你是对的 - 我应该先仔细查看代码。但如果可能的话,我仍然建议使用c++11标志。 - MikeMB
@MikeMB 这确实是一个好观点,因为一些C ++ 11不作为扩展实现,如果代码使用它们,则无法在没有“-std = c ++ 11”的情况下编译。 - vsoftco
3个回答

26

在数组声明后,您不能直接对其进行赋值。基本上,您的代码与以下代码相同:

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

你必须在声明时分配值

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

或者使用循环(或 std::copy)来赋值元素。由于您的数组似乎是一个成员变量,您也可以在构造函数初始化列表中初始化它:

 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
 }

2
当您说:
boundaries = 
{{0,512},{0,512},{0.01,5.},{100.,3000.},{0.1,50}};

这是不正确的,因为C++不允许重新分配数组值。有一个简单的解决方法,但它有些繁琐。你需要一个一个地分配每个值。

例如:

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

等等,我在Arduino程序中遇到了同样的问题。


0

数组本质上只是指针。C++(作为一种基于符号的编程语言)对数组有自己的解释。这意味着:

int* a[3]; 你已经声明了数组,但目前分配给数组的每个元素的值都是一些垃圾值,这些垃圾值已经存储在内存中。

a={1,2,3}; 不起作用,因为:C++将数组名“a”视为指向数组中第一个元素的地址位置的指针。“a”基本上由C++解释为“&a[0]”,即元素a[0]的地址。

所以,你有两种方法来赋值

  1. 使用数组索引(如果你不知道指针是什么,这是你唯一的选择)

    int a[3]; for(int i=0;i<3;++i) // 使用for循环为每个元素分配一个值 { cin>>a[i]; }

2 将其视为指针并使用指针操作

    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)
    }

注意:不能使用++a指针操作,因为++会改变指针的位置,而a+i不会改变指针'a'的位置,而且使用++会导致编译器错误。
建议阅读Stephen Davis的《C++入门指南》。

1
数组不是指针,它们是自己的类型,例如sizeof(int[2][2])等于4 * sizeof(int),而不是sizeof(int*)2 * sizeof(int*)。一个数组可以被分配给适当类型的指针,但它们是不同的类型(我认为这种赋值行为是C和C++中的缺陷)。 - Hugo Burd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接