SFML accessing array inside std::vector - c++

In class A I have:
class A{
A(){};
std::vector<sf::Vertex[2]> lines{ 5 };
};
And I somehow need to access sf::Vertex 0 and 1 of all the line objects in std::vector. The SFML documentation states on lines:
sf::Vertex line[] =
{
sf::Vertex(sf::Vector2f(10, 10)),
sf::Vertex(sf::Vector2f(150, 150))
};
I tried many things, but syntax just doesn't work out, from this:
std::vector lines{ {Vertex(100,100),Vertex( 300,300)},... };
to this:
A(){
lines[0]->sf::Vertex[0] = (100,100);
...};
But it just doesn't work out. What's the proper syntax?

An array is not a valid element type for a vector (or any other standard Container). It doesn't satisfy the requirement of being Erasable. You can instead use a class that has the array as a member. The standard library has a template for such array wrapper: std::vector<std::array<sf::Vertex, 2>>.

Related

Passing a 2d array of vector to a class constructor

In my code, I have some data stored in an 2d array of vector and I'd like to use it in another class to process the data but I can't find a way to do that.
Here is a sample of what I tried :
vector<IndividualData> vecArray[5][5]; // The one I want to pass to the class
MyClass::MyClass(vector<IndividualData> data[][5], ...):_data(data)
Is there a good way to do that?
I also tried with the std::array but I can't make it work :
array<array<vector<IndividualData>, 5>, 5> testVec; // Ther one I want to pass to the class
MyClass::MyClass(array<array<vector<IndividualData>, 5>, 5>& data, ...): _data(data)
When I want to use it in the class, I get the following error :
Type 'array<array<vector, 5>, 5>' does not provide a subscript operator
With
printf("%d\r\n", _data[0][0][0].param);
and
array<array<vector<IndividualData>, 5>, 5>& _data;
Thank's in advance for your replies
This works for me:
using My2DArrayOfVec = std::array<std::array<std::vector<IndividualData>, 5>, 5>;
class MyClass
{
My2DArrayOfVec _data;
public:
MyClass(My2DArrayOfVec const& data, ...) : _data(data) {}
void useIt() const { printf("%d\r\n", _data[0][0][0].param); }
};
By having an alias, I always use the same types, My2DArrayOfVec, inside and outside of my class even when I'm experimenting.

Push to vector while assignment to an array

I need to push some elements into an existing vector as I assign them to an array.
I am able to initialize them and then further copy them, but I need to do both the operations at once.
Say there is a Base class TestBase and derived class TestOne, TestTwo, TestThree. I have initialized them based on the type using an enum as shown.
I do have an existing vector which I want to push these items into.
enum class Type : std::uint8_t {
TYPE_ONE,
TYPE_TWO,
TYPE_THREE
}; //enum class Type
struct _ds {
enum class Type type;
std::shared_ptr<TestBase> p_str;
};
std::vector<std::shared_ptr<TestBase>> vec_base_ptrs;
int main(int argc, char *argv[]) {
_ds a_ds[] = {{Type::TYPE_ONE,std::make_shared<TestOne>()},
{Type::TYPE_TWO,std::make_shared<TestTwo>()},
{Type::TYPE_THREE,std::make_shared<TestThree>()}};
}
Now is there a possibility, where I can do the following, where I can push the pointers into vector as well as have it in array at the same it. Is it possible.
_ds a_ds[] = {{Type::TYPE_ONE,{vec_base_ptrs.push_back(std::make_shared<TestOne>())}},
{Type::TYPE_TWO,{vec_base_ptrs.push_back(std::make_shared<TestTwo>())}},
{Type::TYPE_THREE,{vec_base_ptrs.push_back(std::make_shared<TestThree>())}}};
Please let me know how to do it.
Also suggest if there are any other data structures that can help in solve this problem, with a note that I need to fill the vectors with the shared_ptrs as I am getting it from third party library.

C++ initializer list for std::vector<obj*> as constructor parameter

I have a situation where I need to create instances of a class with many object pointer parameters. But, I'm looking for a simpler way. In this code sample, I demonstrate very generically what I'm trying to do.
#include <vector>
#include <string>
class A
{
public:
A(std::string param);
};
class B
{
public:
B(std::vector<A*> params);
};
int main(int argc, char* argv[])
{
std::vector<A*> my_arguments;
my_arguments.push_back(new A("A1"));
my_arguments.push_back(new A("A2"));
my_arguments.push_back(new A("A3"));
my_arguments.push_back(new A("A4"));
B my_b = new B(my_arguments);
}
I don't like having to use an additional 5 lines to create the parameters for this call. Is there an alternate way to do this that requires less code. I tried using an array like so, but it doesn't seem to be working:
B my_b = new B([new A("A1"), new A("A2"), new A("A3"), new A("A4")]);
How could I achieve a similar result? I thought about using va_list, but that would require another parameter marking the end, or a count of the number of variables. It might be what I end up doing, but, are there any other strategies out there?
You were nearly there...
B my_b{{new A("A1"), new A("A2"), new A("A3"), new A("A4")}};
Note: your code was trying to create B my_b which is not a pointer, so you don't need to use new. The outer { } pair surround the argument to the constructor, the inner { } pair create a std::initializer_list for the std::vector constructor, so the values therein are used to construct the std::vector argument.
Note that this syntax has been supported since C++11 - some compilers needs command line arguments to enable support for the C++11 Standard, e.g. gcc -std=c++11 ....

Sharing the same container between two different classes

Say for example I have the following two classes:
class ChessBoard
{
std::vector <ChessPiece> pieceList;
}
class ChessSquare
{
std::vector <ChessPiece> pieceList;
}
What I want to do is allow both classes to have access to the exact same ChessPiece vector, so that both of them have read/write access to the EXACT SAME ChessPiece data. So say for example when ChessSquare updates the pieceList vector, the corresponding pieceList vector in ChessBoard will get updated as well, and vice-versa. How would I go about implementing this?
Use a pointer. Give them each a copy of the same pointer to the vector.
If you give them each a std::shared_ptr you get the added benefit of reference counting and cleanup handled once neither of the classes are left using it.
Use pointer or reference to the pieceList.
Create object ChessPiece and send pointer of this object to ChessBoard and ChessSquare. I hope you access to ChessPiece only from one thread, instead you have to protect your ChessPiece using mutex or something like that.
Pointer is the obvious choice. BUT if you are feeling crazy and want to over-engineer your project you could encapsulate the vector within its own class and make that class a globally visible singleton
Use pointer maybe a good way, but i think you should achieve your point like this:
class ChessBase
{
static std::vector <ChessPiece> pieceList;
}
class ChessBoard : ChessBase
{
//to do what you want.
}
class ChessSquare : ChessBase
{
//to do what your want.
}
You can access the vector in each class as their member.
Seeing as a chessboard is composed of chess squares, I might suggest having the vector in the chessboard class and a reference to it in the chess square class, maybe like so:
typedef std::vector<ChessPiece> PIECES
class ChessBoard
{
public:
ChessBoard()
{
// NOTE! your app might have more squares than this:
m_pSquare = new ChessSquare( pieceList );
}
private:
PIECES pieceList;
ChessSquare* m_Square;
}
class ChessSquare
{
public:
ChessSquare( const PIECES& pieces )
: refPieceList(pieces)
{
}
private:
const PIECES& refPieceList;
}

How to build a Constructor for a Vector of pointers to classes

I need to build a constructor for a Vector of pointers to classes...
My class is :
class Song {
string song_name;
string auther_name;
int popularity;
SongStructure song_format;
int song_length;
int lengths[size];
bool first_condition_true();
bool second_condition_true(int index);
}
};
My vector is :
vector<Song*> play_list;
With the new standard C++11 / 0x initializer list has been introduced:
I assume you wanted to create a SongBook class containing a vector of Song-Pointers and then additional Infos.
They can be used like this:
Class file:
class SongBook {
vector<Song*> songlist;
string name;
// Constructor
SongBook(std::initializer_list<Song*> songs) : songlist(songs) {}
}
and then call like this from your main for example
SongBook book({new Song(...), new Song(...), new Song(...)});
Your vector have a working constructor that you can use. (It create place for the pointers). What you are asking for is probably a way to make the pointers point to some valid Song. You will need to do that in some loop (STL "loop" probably). But you probably dont need that, becouse your Song is legaly copyable!?. You can use vector<Song>