[英]Defining the length of a vector within a struct
The struct I want to use is defined below. 我要使用的结构定义如下。 (I am using
namespace std
): (我正在使用
namespace std
):
struct body {string name; float m; vector< float > p; vector< float > v;};
This compiles, but later I get a segmentation fault at run time. 这样可以编译,但是后来我在运行时遇到了分段错误。 I know this is because the vectors don't have a defined size (I want three components).
我知道这是因为向量没有定义的大小(我需要三个分量)。
I have tried using the a vector constructor vector x(3,0)
, but this won't compile. 我已经尝试使用向量构造函数
vector x(3,0)
,但这将无法编译。 I get: 我得到:
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);};
Basically, I need to allocate space for a vector of 3 elements when I define the struct, and I do not know how to do this. 基本上,定义结构时,我需要为3个元素的向量分配空间,但我不知道该怎么做。 I am a C++ beginner and have done a lot of research, but I cannot find an answer.
我是C ++初学者,已经做了很多研究,但是找不到答案。 Thanks for any help I can get.
感谢您的任何帮助。
You call the vector constructor inside your constructor. 您可以在构造函数内部调用向量构造函数。
struct body {
string name;
float m;
vector< float > p;
vector< float > v;
body(): p(3,0), v(3,0) {}
};
You can specify the size for the vector in the constructor for your body
: 您可以在
body
的构造函数中指定向量的大小:
struct body {
string name;
float m;
vector< float > p;
vector< float > v;
body() : p(3), v(3) {}
};
C++11 allows you to specify constructor arguments "in place", so something like: C ++ 11允许您“就地”指定构造函数参数,例如:
struct body {
string name;
float m;
vector< float > p{3};
vector< float > v{3};
};
...is allowed, but it sounds like your compiler doesn't support that (maybe time for an update?) ...是允许的,但听起来您的编译器不支持该功能(也许是时候进行更新了?)
Edit: doing a bit of checking, it appears that not all compilers select the correct constructor when given the second piece of code. 编辑:进行一些检查,当给出第二段代码时,似乎并非所有编译器都选择正确的构造函数。 For example, given the code above, VC++ gives a vector containing 3 0's, but g++ gives a vector containing a single value of 3. In other words, g++ is using the overload that takes an initializer list, but VC++ is using the overload that takes one parameter.
例如,给定上面的代码,VC ++给出了一个包含3个0的向量,而g ++给出了一个包含单个值3的向量。换句话说,g ++使用的是带有初始化程序列表的重载,而VC ++使用的是带有初始值列表的重载。接受一个参数。
For whatever it's worth, it appears that g++ is doing this correctly, and VC++ is incorrect 1 , but from a practical viewpoint it's of little consequence: code that uses it isn't portable, so most people probably want to avoid it (at least until the compiler vendors get their acts together). 不管值多少钱,g ++似乎都能正确执行,而VC ++是不正确的1 ,但是从实际的角度来看,这没有什么意义:使用它的代码不是可移植的,所以大多数人可能希望避免这样做(至少直到编译器供应商将他们的行为放在一起为止)。
The specific wording is at $13.3.1.7: 具体文字为$ 13.3.1.7:
std::vector
has an intializer-list constructor, leaving on the question of whether it's viable. std::vector
有一个初始化列表构造函数,剩下的问题是它是否可行。 That comes down to the question of whether converting 3
to a float
is a "narrowing conversion". 这归结为以下问题:将
3
转换为float
是否是“缩小的转换”。 In this case, the answer is no, it's not. 在这种情况下,答案是否定的,不是。 The official wording is (§8.5.4/7):
官方用语是(第8.5.4 / 7节):
A narrowing conversion is an implicit conversion
缩小转换是隐式转换
[ ... ]
[...]
from an integer type or unscoped enumeration type to a floating-point type, except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type,
从整数类型或无作用域枚举类型到浮点类型,除非源是一个常量表达式,并且转换后的实际值将适合目标类型,并在转换回原始类型时会产生原始值,
So, since we're using a constant expression with the value 3
, and float
is guaranteed to be able to hold that value, and produce 3
as the result if we convert it back to int
, it's not a narrowing conversion. 因此,由于我们使用的值为
3
的常量表达式,并且保证float
能够保留该值,并且如果将其转换回int
,则结果将生成3
,这不是缩小的转换。 That means the initializer-list constructor is viable, so it's the one that should be chosen. 这意味着initializer-list构造函数是可行的,因此应该选择它。
In theory, if you want to do the in-place initialization, you should probably use: 从理论上讲,如果要执行就地初始化,则可能应使用:
std::vector<float> p{0, 0, 0};
...MS VC++, however, rejects this, reinforcing the previous advice that if you care about portability, you probably want to avoid this in general. ... MS VC ++拒绝了此建议,从而强化了先前的建议,即如果您关心可移植性,则通常可能希望避免这种情况。
You have a few options: 您有几种选择:
1) add a constructor to initialize the vectors to size 3: 1)添加一个构造函数以将向量初始化为大小3:
struct body
{
body() : p(3), v(3) {}
string name;
float m;
vector< float > p;
vector< float > v;
};
2) initialize the variables at the point of declaration (C++11) 2)在声明时初始化变量(C ++ 11)
struct body
{
string name;
float m;
vector< float > p = vector<float>(3);
vector< float > v = vector<float>(3);
};
3) Use std::array<float, 3>
instead of vectors 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) Use brace initialization to instantiate the struct. 3)使用花括号初始化来实例化结构。
body b1 {"hello", 3.14, vector(3,0), vector(3,0) };
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.