C++ Syntax: Add new vector to a list - c++

Ok, so this is a bit complicated and my syntax memory sucks...
I have a list which holds vectors of objects called "Plane".
Here:
std::list<std::vector<Plane>> possible_planes;
Plane is a class I made.
What I am trying to do now is add new entries to that.
So something like this:
possible_planes.push_back(std::vector<Plane> new Plane(boundRect[i].area(), center[i]));
And here is where I fail to get the syntax right. What does the correct syntax look like?

You code is declaring a variable in the middle of an expression, as well as dynamically allocating when it should not be. Try this:
possible_planes.push_back(std::vector<Plane>());
possible_planes.back().push_back(Plane(boundRect[i].area(), center[i]));
Note, this could be reduced even more if I knew you were using a C++11 compliant toolchain.

1. first create new vector, then add the plane
possible_planes.push_back(std::vector<Plane>());
possible_planes.back().push_back(Plane(boundRect[i].area(), center[i]));
2. have a function like this one
std::vector<Plane> createNewPlaneVector(Plane& plane) {
std::vector<Plane> result;
result.push_back(plane);
return result;
}
then you can add then new vector in one line
possible_planes.push_back(createNewPlaneVector(Plane(boundRect[i].area(), center[i])));
If you are using C++11 then this gets simpler:
possible_planes.push_back(std::vector<Plane>() { Plane(boundRect[i].area(), center[i]) } );

Maybe try doing it with multiple lines and variables, like this:
vector<Plane> newPlane; // Vector you add to list later
Plane myPlane; // Your object
// Do what you want with your Plane object
newPlane.push_back(myPlane); // Insert your object to vector
possible_planes.push_back(newPlane); // Insert vector to list

Related

Initialize a Matrix of Pairs in Constructor

I'm creating a boardgame (Tzaar if curious :D) in openGL and I need to initialize my logical board with the starting pieces in each place.
In my Game classe I have the following variable:
std::pair<char,int> logicBoard[17][9];
and want to initialize it in the constructor following somewhat this example:
logicBoard[][] = {
{(0,0),(0,0),(0,0),(0,0),('z',1),(0,0),(0,0),(0,0),(0,0)},
{(0,0),(0,0),(0,0),('c',1),(0,0),('z',1),(0,0),(0,0),(0,0)},
{(0,0),(0,0),('c',1),(0,0),('y',1),(0,0),('z',1),(0,0),(0,0)},
{(0,0),('c',1),(0,0),('b',1),(0,0),('y',1),(0,0),('z',1),(0,0)},
{('c',1),(0,0),('b',1),(0,0),('x',1),(0,0),('y',1),(0,0),('c',1)},
{(0,0),('b',1),(0,0),('a',1),(0,0),('x',1),(0,0),('b',1),(0,0)},
{('z',1),(0,0),('a',1),(0,0),('z',1),(0,0),('a',1),(0,0),('c',1)},
{(0,0),('y',1),(0,0),('c',1),(0,0),('c',1),(0,0),('b',1),(0,0)},
{('z',1),(0,0),('x',1),(0,0),(0,0),(0,0),('a',1),(0,0),('c',1)},
{(0,0),('y',1),(0,0),('z',1),(0,0),('z',1),(0,0),('b',1),(0,0)},
{('z',1),(0,0),('x',1),(0,0),('c',1),(0,0),('x',1),(0,0),('c',1)},
{(0,0),('y',1),(0,0),('a',1),(0,0),('x',1),(0,0),('y',1),(0,0)},
{('z',1),(0,0),('b',1),(0,0),('a',1),(0,0),('y',1),(0,0),('z',1)},
{(0,0),('c',1),(0,0),('b',1),(0,0),('y',1),(0,0),('z',1),(0,0)},
{(0,0),(0,0),('c',1),(0,0),('b',1),(0,0),('z',1),(0,0),(0,0)},
{(0,0),(0,0),(0,0),('c',1),(0,0),('z',1),(0,0),(0,0),(0,0)},
{(0,0),(0,0),(0,0),(0,0),('c',1),(0,0),(0,0),(0,0),(0,0)}
};
But since I'm not so in depth of C++, don't know the easiest way of doing so.
Want it to be easily modified too since the board will be sent to Prolog (with the game logic) program through sockets, so it returns the modified board again to this variable.
Why not use a Container to better management of your pairs?
It would be like this:
std::vector< std::pair<char,int> > logicBoard;
logicBoard.push_back({0, 1});
logicBoard.push_back({'c', 1});
And so on...
This way if you ever need, lets say, the size of your "array" you can simply use logicBoard.size();
I would define a typedef, and here is a compilable snippet
typedef std::pair<char,int> P;
P logicBoard[17][9] = {
{P(0,0),P(0,0),P(0,0),P(0,0),P('z',1),P(0,0),P(0,0),P(0,0),P(0,0)},
{P(0,0),P(0,0),P(0,0),P('c',1),P(0,0),P('z',1),P(0,0),P(0,0),P(0,0)},
{P(0,0),P(0,0),P('c',1),P(0,0),P('y',1),P(0,0),P('z',1),P(0,0),P(0,0)},
{P(0,0),P('c',1),P(0,0),P('b',1),P(0,0),P('y',1),P(0,0),P('z',1),P(0,0)},
{P('c',1),P(0,0),P('b',1),P(0,0),P('x',1),P(0,0),P('y',1),P(0,0),P('c',1)},
{P(0,0),P('b',1),P(0,0),P('a',1),P(0,0),P('x',1),P(0,0),P('b',1),P(0,0)},
{P('z',1),P(0,0),P('a',1),P(0,0),P('z',1),P(0,0),P('a',1),P(0,0),P('c',1)},
{P(0,0),P('y',1),P(0,0),P('c',1),P(0,0),P('c',1),P(0,0),P('b',1),P(0,0)},
{P('z',1),P(0,0),P('x',1),P(0,0),P(0,0),P(0,0),P('a',1),P(0,0),P('c',1)},
{P(0,0),P('y',1),P(0,0),P('z',1),P(0,0),P('z',1),P(0,0),P('b',1),P(0,0)},
{P('z',1),P(0,0),P('x',1),P(0,0),P('c',1),P(0,0),P('x',1),P(0,0),P('c',1)},
{P(0,0),P('y',1),P(0,0),P('a',1),P(0,0),P('x',1),P(0,0),P('y',1),P(0,0)},
{P('z',1),P(0,0),P('b',1),P(0,0),P('a',1),P(0,0),P('y',1),P(0,0),P('z',1)},
{P(0,0),P('c',1),P(0,0),P('b',1),P(0,0),P('y',1),P(0,0),P('z',1),P(0,0)},
{P(0,0),P(0,0),P('c',1),P(0,0),P('b',1),P(0,0),P('z',1),P(0,0),P(0,0)},
{P(0,0),P(0,0),P(0,0),P('c',1),P(0,0),P('z',1),P(0,0),P(0,0),P(0,0)},
{P(0,0),P(0,0),P(0,0),P(0,0),P('c',1),P(0,0),P(0,0),P(0,0),P(0,0)}
};
BTW depending on your Prolog interface that should be adaptable to actually exchange values. In case, maybe you want to keep P lowercase.

How do you create an array of member function pointers with arguments?

I am trying to create a jump table for a fuzzy controller. Basically, I have a lot of functions that take in a string and return a float, and I want to be able to do something along the lines:
float Defuzzify(std::string varName, DefuzzificationMethod defuzz)
{
return functions[defuzz](varName);
}
where DefuzzificationMethod is an enum. The objective is to avoid a switch statement and have a O(1) operation.
What I have right now is:
float CenterOfGravity(std::string varName);
std::vector<std::function<float (std::string)>> defuzzifiers;
Then I try to initialize it in the constructor with:
defuzzifiers.reserve(NUMBER_OF_DEFUZZIFICATION_METHODS);
defuzzifiers[DEFUZZ_COG] = std::bind(&CenterOfGravity, std::placeholders::_1);
This is making the compiler throw about 100 errors about enable_if (which I don't use anywhere, so I assume std does). Is there a way to make this compile ? Moreover, is there a way to make this a static vector, since every fuzzy controller will essentially have the same vector ?
Thanks in advance
Reserve just makes sure there's enough capacity, it doesn't actually mak the vector's size big enough. What you want to do is:
// construct a vector of the correct size
std::vector<std::function<float (std::string)>> defuzzifiers(NUMBER_OF_DEFUZZIFICATION_METHODS);
// now assign into it...
// if CentorOfGravity is a free function, just simple = works
defuzzifiers[DEFUZZ_COG] = CenterOfGravity;
// if it's a method
defuzzifiers[DEFUZZ_COG] = std::bind(&ThisType::CenterOfGravity, this, std::placeholders::_1);
Now this might leave you some holes which don't actually have a function defined, so maybe you want to provide a default function of sorts, which the vector constructor allows too
std::vector<std::function<float (std::string)>> defuzzifiers(
NUMBER_OF_DEFUZZIFICATION_METHODS,
[](std::string x) { return 0f; }
);
An unrelated note, you probably want your functions to take strings by const-ref and not by value, as copying strings is expensive.

Remove element from vector error C++

I know this might seem as a duplicate question, but it is not, I have a problem with a function and don''t know why it behaves like that.
I have a vector which holds elements of type MyMaterial** (std::vector). At a point in my program, I will know an element, "currentElement", and I will want to remove it.
I tried doing this:
myMaterials.erase(currentElement);
But here is the problem: Instead of only deleting "currentElement", it also deletes all elements added after it. Why does it do that and how can I solve it?
I must mention that I don''t know the position of "currentElement" in the vector, and i prefere not to search for it, I''m hoping there is another way.
If you are using std::vector, then:
Erase elements Removes from the vector either a single element
(position) or a range of elements ([first,last)).
Maybe you are looking for something like this:
How do I remove an item from a stl vector with a certain value?
To use vector::erase(iterator) to remove an element from a vector, you may either have to know its index OR iterate thru the list to hunt for it.
Luckily, There is the std::map, and this is how you would work it
std::map<std::string,myMaterial> myMaterials;
myMaterial mat;//assuming it doesnt take any args
myMaterials['myMaterialXYZ'] = mat; ///add it to the array
myMaterials.erase('myMaterialXYZ'); ///Erase by key..(or "name" in this case)
Now you can easily track string names instead of ever changing index positions...and memory locations, which by the way may be another ace up your sleeve.
I couldn''t really use the examples given by you above, because I got all kinds of errors, due to the type of elements the vector holds. But I made a function which managed to delete the specific element:
int i=0;
int found=0;
MyMaterial **material = gMaterials.begin();
while(material != gMaterials.end() && found == 0)
{
if(currentElement == material)
{
gMaterials.erase(gMaterials.begin() + i, gMaterials.begin() + i+1);
found = 1;
}
i++;
cloth++;
}
I don''t know how good/correct it is, but it does the job.
Thank you very much for the suggestions and the help.

C++ pass STL container items as reference

I have a map of type std::map<std::string, std::vector<MyClass>>. The map is filled in this way that I create a vector and put it with a guid as a pair into the map. Then I want to call a function, give the just inserted vector to it and let it fill the vector. It looks like that:
{
std::string guid = "aGUID"
std::vector<MyClass> vec_myClass(0);
my_map[guid] = vec_myClass;
std::vector<MyClass>& vec_ref = my_map[guid];
FillVector(vec_ref);
}
FillVector(std::vector<MyClass>& vec) { vec.push_back(...); }
I think the [] operator returns a reference of the item in my_map, which I can give to a function to work with it, but my application crashes at this point. I am putting the vector first into the map (when it is empty) because I want to avoid copying effort as function FillVector puts lots of items into the vector. Where is my mistake? Might it be wrong to pass a reference by reference to a function? Or is there a clearly better solution to this? I prefer references over pointers here. Thx, and all the best.
All that code simplifies to:
{
std::string guid = "aGUID"
FillVector(my_map[guid]);
}
Btw. I think your problem does not appear to be here, but in code you don't show us...
std::map operator would create value for the key internally if it does not exist. see this link. passing the reference to function is ok, the problem seem to be somewhere else in your code.

Creating "Item" definitions

I am trying to think of a good way to define base-items for a small game I am creating in C++ using DirectX. Right now the structure would look something like:
struct itemdef {
string name;
ID3DXMesh* mesh;
vector<IDirect3DTexture9*> textures;
vector<short> abilities;
};
The problem I am having is I essentially want to make an array of these base properties without creating an upper limit for textures or abilities.
Essentially imagine it as having another array of "itemdef"
vector<itemdef> itemDefs;
and then wanting to add items to this array, either hardcoded or from a file:
itemDefs.push_back(NewItem("Wall", Assets.GetMesh(Mesh_Wall), ???, ???));
Basically, I have no idea how to put multiple single items into a parameter list for a vector array. The second problem being the need to create two lists in one set of arguments.
So my question is: What should replace the "???" fields in that statement above? Or, failing that, what better method should I use to store these basic definitions?
(for clarity: Pointers for textures are obtained virtually the same way as the mesh above was and the "abilities" are just short ints. Although it should be noted that for these definitions both meshes and textures could just be replaced with their enumerations rather than pointers)
I would build up the vector's first as local variables and then send them to the item constructor:
vector<IDirect3DTexture9*> tex;
vector<short*> abil;
// fill them with the data you need
itemDefs.push_back(NewItem("Wall", Assets.GetMesh(Mesh_Wall), tex, abil));
itemdef NewItem(const string& name, ID3DMesh* mesh, const vector<IDirect3DTexture9*>& textures, const vector<short*>& abilities)
{
itemdef retval;
retval.name = name;
retval.mesh = mesh;
retval.textures = textures;
retval.abilities = abilities;
return retval;
}
Alternatively you could write some function which builds and returns the vector's.
PS: Why do you use some global NewItem-function instead of a constructor?