定义结构中向量的长度

时间:2013-10-28 19:10:35

标签: c++ vector struct std

我想要使用的结构定义如下。 (我正在使用namespace std):

struct body {string name; float m; vector< float > p; vector< float > v;};

这个编译,但后来我在运行时遇到了分段错误。我知道这是因为矢量没有定义的大小(我想要三个组件)。

我尝试过使用矢量构造函数vector x(3,0),但这不会编译。我明白了:

glib.h(5): error: expected a type specifier
  struct body {string name; float m; vector<float> p (3,0); vector<float> v(3,0);};
                                                      ^

glib.h(5): error: expected a type specifier
  struct body {string name; float m; vector<float> p (3,0); vector<float> v(3,0);};
                                                        ^

glib.h(5): error: expected a type specifier
  struct body {string name; float m; vector<float> p (3,0); vector<float> v(3,0);};
                                                                            ^

glib.h(5): error: expected a type specifier
  struct body {string name; float m; vector<float> p (3,0); vector<float> v(3,0);};

基本上,我需要在定义结构时为3个元素的向量分配空间,我不知道如何做到这一点。我是一名C ++初学者并做了很多研究,但我找不到答案。感谢您提供的任何帮助。

3 个答案:

答案 0 :(得分:1)

在构造函数中调用向量构造函数。

struct body {
    string name; 
    float m; 
    vector< float > p; 
    vector< float > v;

    body(): p(3,0), v(3,0) {}
};

答案 1 :(得分:1)

您可以在body的构造函数中指定向量的大小:

struct body {
    string name; 
    float m; 
    vector< float > p; 
    vector< float > v;

     body() : p(3), v(3) {}
};

C ++ 11允许您“就地”指定构造函数参数,例如:

struct body {
    string name; 
    float m; 
    vector< float > p{3}; 
    vector< float > v{3};
};

...是允许的,但听起来你的编译器不支持(也许是时候进行更新了?)

编辑:进行一些检查,看来并非所有编译器在给出第二段代码时都选择了正确的构造函数。例如,给定上面的代码,VC ++给出一个包含3 0的向量,但是g ++给出了一个包含单个值3的向量。换句话说,g ++使用带有初始化列表的重载,但VC ++正在使用重载拿一个参数。

无论它的价值如何,似乎g ++正确地执行了这一操作,并且VC ++不正确 1 ,但从实际角度来看,这并不重要:使用它的代码不可移植,所以大多数人可能都想避免它(至少在编译器供应商一起行动之前)。


  1. 具体措辞为13.3.1.7美元:

    • 最初,候选函数是类T的初始化列表构造函数(8.5.4),参数列表由初始化列表作为单个参数组成。
    • 如果找不到可行的初始化列表构造函数,则再次执行重载解析,其中候选函数是类T的所有构造函数,参数列表由初始化列表的元素组成。
  2. std::vector有一个初始化列表构造函数,留下它是否可行的问题。这归结为将3转换为float是否为“缩小转化”的问题。在这种情况下,答案是否定的,但事实并非如此。官方措辞是(§8.5.4/ 7):

      

    缩小转化是隐式转化

         

    [...]

         

    从整数类型或无范围枚举类型到浮点类型,除非源是常量表达式,转换后的实际值将适合目标类型,并在转换回原始值时生成原始值型,

    因此,由于我们使用值为3的常量表达式,并且float保证能够保存该值,并且如果我们生成3将其转换回int缩小转化。这意味着初始化列表构造函数是可行的,因此应该选择它。

    理论上,如果你想进行就地初始化,你应该使用:

    std::vector<float> p{0, 0, 0};
    

    ...但是,MS VC ++拒绝这一点,强化了之前的建议,即如果你关心可移植性,你可能想要避免这种情况。

答案 2 :(得分:1)

您有几个选择:

1)添加构造函数以将向量初始化为大小为3:

struct body 
{
  body() : p(3), v(3) {}
  string name; 
  float m; 
  vector< float > p; 
  vector< float > v;
};

2)在声明点(C ++ 11)初始化变量

struct body 
{
  string name; 
  float m; 
  vector< float > p = vector<float>(3); 
  vector< float > v = vector<float>(3);
};

3)使用std::array<float, 3>代替向量

struct body 
{
  body() : p(3), v(3) {}
  string name; 
  float m; 
  std::array<float, 3> p; 
  std::array<float, 3> v;
};

3)使用大括号初始化来实例化结构。

body b1 {"hello", 3.14, vector(3,0), vector(3,0) };