Reputation: 193
The struct I want to use is defined below. (I am using 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. 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. I am a C++ beginner and have done a lot of research, but I cannot find an answer. Thanks for any help I can get.
Upvotes: 1
Views: 1973
Reputation: 490108
You can specify the size for the vector in the constructor for your 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:
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.
For whatever it's worth, it appears that g++ is doing this correctly, and VC++ is incorrect1, 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).
The specific wording is at $13.3.1.7:
std::vector
has an intializer-list constructor, leaving on the question of whether it's viable. That comes down to the question of whether converting 3
to a float
is a "narrowing conversion". In this case, the answer is no, it's not. The official wording is (§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. That means the initializer-list constructor is viable, so it's the one that should be chosen.
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.
Upvotes: 1
Reputation: 227400
You have a few options:
1) add a constructor to initialize the vectors to size 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)
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
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.
body b1 {"hello", 3.14, vector(3,0), vector(3,0) };
Upvotes: 2
Reputation: 264391
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) {}
};
Upvotes: 1