0

我要使用的结构定义如下。(我正在使用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++ 初学者,已经做了很多研究,但我找不到答案。感谢我能得到的任何帮助。

4

3 回答 3

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 的所有构造函数,参数列表由初始化列表的元素组成。

std::vector有一个初始化列表构造函数,留下它是否可行的问题。这归结为转换3为 afloat是否是“缩小转换”的问题。在这种情况下,答案是否定的,不是。官方措辞是(§8.5.4/7):

缩小转换是隐式转换

[ ... ]

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

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

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

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

...但是,MS VC++ 拒绝了这一点,并强化了先前的建议,即如果您关心可移植性,则通常可能希望避免这种情况。

于 2013-10-28T19:24:14.777 回答
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) };
于 2013-10-28T19:24:49.747 回答
1

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

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

    body(): p(3,0), v(3,0) {}
};
于 2013-10-28T19:23:18.950 回答