How do i create a stack of multidimentional arrays - c++

i know how to create a stack of vectors or int ,etc. But i dont know how to create a stack of a multidimentional arrays t[n][n] . Whats the way to implement it?
this is my actual implementation which its not working.
char map[20][20];
stack<map> soluciones;
Edit:
I think due my english most of you didnt undestand my question. Imagine i got some kind of a Game map. I am saving each multidimentional array on the stack. Thats my objective saving the map on a stack
Edit 2: im using Visual Studio 2010 Windows form application

In your code example, you use map (the name of your variable) in place of where a type name must stand (in stack<map> template instantiation). However, it won't work, not even if you use the proper type name (in this case you'd have to use typedef, e.g. typedef char TwoDimCharArray[20][20] and then try std::stack<TwoDimCharArray>:
There is still the problem that arrays don't have a default constructor (which std::stack expects); therefore, std::stack cannot be made to directly contain arrays; you'd have to wrap the array inside a class or struct (which can have a default constructor), e.g.:
class TwoDimCharArray
{
public:
// omit if there's nothing to initialize in map, then the
// compiler-generated constructor will be used
TwoDimCharArray()
{
// ... initalize map values
}
// ... provide access methods to map
private:
char map[20][20];
};
std::stack<TwoDimCharArray> soluciones;
Or use Boost.Array or C++11 std::array stuff! If these are available, they are definitely the better and easier choice!

I guess you should define a proper class for the game map. Then the stack of game maps is not a problem.
class GameMap {
public:
...
private:
char map_[1000][1000];
};
Then it wont matter for the stack how you allocate and manage the map data. E.g.
typedef std::stack<GameMap> GameMapStack;

Ddefine a wrapper class for multidimentional arrays like this:
template <class T, int X, int Y>
class Wrapper
{
public:
T array[X][Y];
}
Then use stack<Wrapper<char, 20, 20> >

First create structure and then define an empty multidimensional char array. then close structure and after thar write push and pop operations.

Related

How to make an object take and store an Array of arbitrary, but compile-time known size?

Background
For an embedded project, I want a class that takes a list of structs. This list is known at compile-time, so I shouldn't have to resort to dynamic memory allocation for this.
However, how do I make a struct/class that encapsulates this array without having to use its size as a template parameter?
Templates
My first idea was to do exactly that:
struct Point {
const uint16_t a;
const double b;
};
template<size_t n>
struct Profile {
Array<Point, n> points;
Profile(const Array<Point, n> &points) : points(points) {}
};
Here, Profile is the class that stores/encapsulates the array of points (the 2-member structs). n, the size of the array, is a template parameter.
I'm using this implementation of Array, similar to std::array, btw, because I don't have access to the STL on this embedded platform.
However, no I have another class that uses this Profile that now also has to be templated because Profile is templated with the size of the array:
template<size_t n>
class Runner {
private:
const Profile<n> profile;
public:
Runner(const Profile<n> &profile) : profile(profile) {};
void foo() {
for(auto point : profile.points) {
// do something
}
}
};
As can be seen, this Runner class operates on a Profile and iterates over it. Having to template Runner is not that much of an issue by itself, but this Runner in turn is used by another class in my project, because this other class calls Runner::foo(). Now I have to template that class as well! And classes that use that class, etc.
That's getting out of hand! What started with just one template parameter to specify the size, now propagates through my entire application. Therefore, I don't think this is a good solution.
Question
Is there a way to 'hide' the size of the array in Profile or Runner? Runner only needs to iterate over it, so the size should in principle only affect its implementation, not its public interface. How would I do that, though?
Also, can I avoid having to manually specify n at all, and just pass an array to Profile's constructor and let the compiler figure out how big it is? At compile-time, of course. I feel like this should be possible (given this array is known at compile-time), but I don't know how exactly.
Other approaches
Macros
I could write a macro like
#define n 12
and include that in both the Profile.h and the place where I instantiate a Profile. This feels dirty though, I and would like to avoid macros.
Vector
I could avoid this fuss by just using a std::vector (or equivalent) instead, but that is allocated at run-time on the heap, which I would like to avoid here since it shouldn't be necessary.
Is there a way to 'hide' the size of the array in Profile or Runner?
Yes. The solution is indirection. Instead of storing the object directly, you can point to it. You don't need to know the size of what you're pointing at.
A convenient solution is to point into dynamic storage (for example std::vector) because it allows you to "bind" the lifetime of the dynamically sized object to a member. That's not necessary in general, and you can use automatic storage instead. However, in that case you cannot bind the lifetime of the pointed object, and you must be very careful to not let the pointed object be destroyed before you stop using it.
The indirection can be done at whatever level you prefer. If you do it at the lowest level, you simply store the array outside of Profile. In fact, if all that profile does is contain an array, then you don't need a class for it. Use a generic span:
struct Runner {
span<const Point> profile;
void foo() {
for(auto point : profile) {
// do something
}
}
};
Point points[] {
// ... number of points doesn't matter
};
Runner runner {
.profile = points,
};
By span, I mean something like std::span. If you cannot use the standard library, then use another implementation. It's basically just a pointer and size, with convenient template constructor.
To clarify, you can pick any two, but you cannot have all three of these:
Lifetime of the array bound to the class (safe)
No compiletime constant size
No dynamic storage
1,2 (no 3) = std::vector, RAII
1,3 (no 2) = std::array, templates, no indirection
2,3 (no 1) = std::span, be careful with lifetimes
I'll expand on this comment:
The idea is that Runner takes Profiles no matter their size. Runner needs to iterate over it, but apart from that, its behaviour is always the same. The class using Runner and calling Runner::foo() doesn't need to know the size. The problem with templating Runner is that the class using Runner also needs to be templated, and the classes using that, etc.
This is only a problem when the class is using the templated Runner directly. It has more dependencies than it actually needs. If it doesn't need to know about the size of the array, then it should not know about the size of the array. If runtime polymorphism is an option you can add a base class that allows accessing the array elements, but doesn't need to know anything about the arrays size. The following is only a sketch:
#include <iostream>
struct RunnerInterface {
virtual int* begin() = 0;
virtual int* end() = 0;
virtual ~RunnerInterface(){}
};
template <unsigned size>
struct Runner : RunnerInterface {
int data[size];
int* begin() override { return data; }
int* end() override { return data+size; } // pointer one past the end if fine (it won't get dereferenced)
};
void foo(RunnerInterface& ri) {
for (auto it = ri.begin(); it != ri.end(); ++it){
*it = 42;
}
}
void bar(RunnerInterface& ri){
for (auto it = ri.begin(); it != ri.end(); ++it){
std::cout << *it;
}
}
int main() {
Runner<42> r;
foo(r);
bar(r);
}
Now if a class needs a Runner member, they store a std::unique_ptr<RunnerInterface> and only on construction you need to decide for the size of the array (though you still need to decide for the size somewhere).

Declaring array of objects without specified size as class field

The field has to be immutable so I can't use the vector. Is there a way to do it like in the title?
I want to do something like this:
typedef list<pair<int,string>> list_pair;
class tree{
private:
list_pair arr[]{
public:
tree(int size){
arr[size];
}
}
Is there a way to do it like in the title?
No.
A non-static member array must have a known size, there is no way around that in C++.
The field has to be immutable so I can't use the vector.
Your example array of non-const isn't immutable either.
Furthermore, I don't see a reason why that should matter. It's a private member, so it's fairly easy to choose to not mutate it. That way the class remains effectively immutable from the outside. Conclusion: Use std::vector.

2D struct array member variable with varying sizes

So I've got a class that I'm generalizing into a base class. One of the member variables is a 2D array of a struct.
struct SomeType
{
...
}
and then in the class's header:
SomeType member_variable_ [SIZE_ONE][SIZE_TWO];
But, in my situation, SIZE_TWO needs to be set when the class is initialized because it's going to be different depending on what's using this. What's the best way to have a 2D struct array with a size that's not yet set as a member variable?
The simplest way to solve it is to not use C-style arrays at all, but to use std::vector. Or possibly an std::array of vectors:
std::array<std::vector<SomeType>, SIZE_ONE> member_variable_;
Now you can easily insert as many (or as few) SomeType objects as needed, and still use the array-indexing syntax:
member_variable_[some_index][some_other_index]
To set a fixed size at runtime for the "second" Dimension, you can do something like this in the constructor:
for (auto& v : member_variable_)
v = std::vector<SomeType>(the_runtime_size);
You could use a template:
template<unsigned SIZE_TWO>
class theClass
{
SomeType member_variable_ [SIZE_ONE][SIZE_TWO];
SIZE_TWO will be set when you instantiate the class.
theClass<5> tc; //member_variable_ [SIZE_ONE][5];
You could also use containers like std::vector or std::array.

Anonymous union/structure holding a generic vector

I'm trying to create an anonymous union that holds a generic vector in order to use it as a member in a class without naming the type_name of the union itself.
So that I could call the vector inside the class as following:
vec.size();
But my approach
template <typename T>
union{
std::vector<T> vec;
};
will only give me the error "template class without a name". This also happens with structures. So does it not like to be anonymous when it is generic?
Search results just gave me the option to create a generic vector inside a named structure but, besides I couldn't get this to work either, I would loose the benefits of the anonymous union und I would need to call the vector e.g. as
struct_name.vec.size();
or even
class_name.struct_name.vec.size();
which I tried to avoid.
I want to make the vector generic so that it can store integers or doubles and I don't need to declare two different vectors with their own specific data types. Beside learning some principles of generics I also aim for lesser declarations and storage usage with this technique.
You cannot reliably do what you want. You need at least some way to discriminate at runtime if you have a vector of int or a vector of float.
With C++11 you might code
class StrangeVector {
bool has_int;
union {
std::vector<int> vint;
std::vector<float> vfloat;
};
public:
StrangeVector(bool withints) : has_int(withints) {
if (withints) new(&vint) std::vector<int>();
else new(&vfloat) std::vector<float>();
}
~StrangeVector() {
if (has_int) vint.~vector<int>();
else vfloat.~vector<float>();
}
};
But such code is really bad smelling. (I would suggest using a union of pointers, perhaps of smart pointers e.g. std::shared_ptr or std::unique_ptr, or perhaps std::optional; see this).
See also this, or boost::any ...
Notice that except for RTTI typing information is used at compile time in C++.

How to add a method to a superclass from a subclass in C++

What I have:
Vectors of different custom structs(one custom struct per vector)
I used pointers to each struct to give it a static size per record
A vector that combines these vectors via a pointer to each
When I try to cast a pointer to the custom vector it fails on every iteration
My workaround is a call to a function that takes the vector pointer as an argument and returns a void pointer.
I know this is wrong despite being functional, but I can't find a reference on the right way to define the cast method properly.
I'm looking for the right way to accomplish this.
typedef struct mystruct {
DWORD something;
vectorclassa * somethinga;
vectorclassb * somethingb;
};
typedef std::vector&ltmystruct*&gt amystruct;
void * theWrongWay(mystruct * apointer){
return apointer;
}
typedef std::vector bigvector;
If I try to bigvector.push_back(&instance_of_amystruct)
It fails. If I change std::vector<amystruct*> bigvector to a void* and call theWrongWay with a &amystruct instance, it compiles/runs. It just seems wrong.
The problem is that I don't know how to define the missing method for vector or cast it to something vector knows how to deal with without doing something...bad.
It's very hard to answer this question because it's hard to tell why you want to do this. Why do you want to keep vectors of different types in another vector?
Anyway, I'll just assume that you want to do this because there's some common action you want to take on each vector. Then you can simply define an abstract class that defines that action, and have a templated child class of this class that keep a different vector depending on the template argument. You can then keep the vectors in a container referring to them as their common ancestor. Some code:
class ActionableVector {
virtual void doSuperCoolStuff() = 0;
}
template<typename T>
class VectorHandler: public ActionableVector {
vector<T> handledVector;
// vector<T> & handleVector; // You can keep a reference to an external vector too
virtual void doSuperCoolStuff() {
//do super cool stuff in a type-safe manner
}
}
template<>
class VectorHandler<ATypeThatNeedsSpecialAttention>: public ActionableVector {
Vector<ATypeThatNeedsSpecialAttention> handledVector;
virtual void doSuperCoolStuff() {
// Do especially cool stuff
}
vector<ActionableVector*> myVectors;
for(ActionableVector * av: myVectors ) { //C++ 11 yaay
av->doSuperCoolStuff();
}
If you really really really want to keep objects of completely different types in a container, and willing to sell your soul to the devil for that, look at this answer.