PDA

View Full Version : Pointer to 2D Vector



squeegedog
5th March 2014, 10:03
Hi All!

I have created several 2D vectors, all operating in the same fashion, and a hopeful pointer for them



QVector< QVector<MapSpace> > p1map;
QVector< QVector<MapSpace> > p2map;
QVector< QVector<MapSpace> > p3map;
QVector< QVector<MapSpace> > p4map;
QVector< QVector<MapSpace> >* pathfix;


I have a function which given particular cases, will modify one of the p1-p4maps. Rather than having to create different instances for each particular map I'm modifying, I was hoping to point pathfix to the map needing updating, allowing the one instance of the function to modify the desired map. However, I cannot seem to figure out how to declare and assign the pointer in a manner that will grant access to the public functions of a MapSpace. I can take out the * before pathfix and do


pathfix = p1map;

But this does not actually change p1map and results in a lot of extra operations in copying the entire matrix. I could later assign p1map the value of pathfix, but this would result in double the matrix copy operations. All of this seems easily avoidable if I can point to the entire 2D vector.

Note: I was hoping to be able to access using [][] notation on my pointer.

Thanks!

Added after 12 minutes:


But this does not actually change p1map and results in a lot of extra operations in copying the entire matrix. I could later assign p1map the value of pathfix, but this would result in double the matrix copy operations. All of this seems easily avoidable if I can point to the entire 2D vector.

After walking away for a moment, this statement may not be entirely correct, I'm still debugging a lot of my recent changes so I haven't been able to see what happens.

Directly assigning one vector to another might be the solution, but it depends on if the variable is actually a pointer as in C++ arrays.

sonulohani
5th March 2014, 11:09
Do like this:-

pathfix = &p1map;

squeegedog
5th March 2014, 18:41
Do like this:-

pathfix = &p1map;

I should have noted some of the things I've tried to this point.


QVector< QVector<MapSpace> > pathfix;
Returns error:
error: no match for 'operator=' in 'pathfix = &((GameScene*)this)->GameScene::p1map'


QVector< QVector<MapSpace> >* pathfix;
error: 'class QVector<MapSpace>' has no member named 'ispassable'


QVector< QVector<MapSpace> >** pathfix;
cannot convert 'QVector<QVector<MapSpace> >*' to 'QVector<QVector<MapSpace> >**' in assignment

ChrisW67
5th March 2014, 22:44
None of the lines and errors you show match the declarations you show. The errors are associated with assignments or some undisclosed call to ispassable(). We cannot fix what we cannot see.

In any case, since the vector must exist why not just pass the QVector by reference (const or not)?



#include <QtCore>

struct MapSpace { };

void someFunc(QVector< QVector<MapSpace> >* v) {
qDebug() << Q_FUNC_INFO << v->size();
v->append(QVector<MapSpace>());
}

void someOtherFunc(QVector< QVector<MapSpace> > &v) {
qDebug() << Q_FUNC_INFO << v.size();
v.append(QVector<MapSpace>());
}


int main(int argc, char **argv) {
QCoreApplication app(argc, argv);

QVector< QVector<MapSpace> > p1map(10); // different initial sizes for demonstration
QVector< QVector<MapSpace> > p2map(5);
QVector< QVector<MapSpace> > *pathfix = 0;

pathfix = &p1map; // no error
someFunc(pathfix); // no error here either
pathfix = &p2map;
someFunc(pathfix);

// Save yourself some typing
someFunc(&p1map);
someFunc(&p2map);

// Or pass by reference
someOtherFunc(p1map);
someOtherFunc(p2map);

return 0;
}

squeegedog
5th March 2014, 23:08
None of the lines and errors you show match the declarations you show. The errors are associated with assignments or some undisclosed call to ispassable(). We cannot fix what we cannot see.

Sorry, I thought it was clear that I was showing the different errors received when I ran the line

pathfix = &p1map
Based on how I declared the variable pathfix. The errors with ispassable() was showing that I could not access the public member functions of the Mapspace when instantiating the pointer in that manner. All of the code being ran operated flawlessly before I realized I had a need to create more than one 2d vector.

The problem I'm facing with using your proposed solution is that this methodology of determining which map to use will be used in several functions, and most of them are being called by a class that is not aware of the 2d vectors

ChrisW67
6th March 2014, 02:01
Sorry, I thought it was clear that I was showing the different errors received when I ran the line

pathfix = &p1map
Based on how I declared the variable pathfix.


// Fails because you are assigning a pointer to a non-pointer variable.
QVector< QVector<MapSpace> > pathfix;
pathfix = &p1map;

// Does not fail. Your error message is from unrelated code.
QVector< QVector<MapSpace> >* pathfix;
pathfix = &p1map;

// Fails because a pointer-to-QVector<...> is not a pointer-to-pointer-to-QVector<...>
QVector< QVector<MapSpace> >** pathfix;
pathfix = &p1map;



The errors with ispassable() was showing that I could not access the public member functions of the Mapspace when instantiating the pointer in that manner.
This is one way you would access an MapSpace function given a pointer to the nested vectors:


#include <QtCore>

struct MapSpace {
void func() { qDebug() << Q_FUNC_INFO;}
void constFunc() const { qDebug() << Q_FUNC_INFO; }
};

void someFunc(QVector< QVector<MapSpace> >* v) {
qDebug() << Q_FUNC_INFO;

for (int i = 0; i < v->size(); ++i) { // outer vector
for (int j = 0; j < v->at(i).size(); ++j) { // inner vector
qDebug() << i << j;
// +- returns const reference to a QVector<MapSpace>
// | + returns const reference to a MapSpace
// | | + on which we call
// V V V
v->at(i).at(j).constFunc();

// +- returns non const reference to a QVector<MapSpace>
// | + returns non-const reference to a MapSpace
// | | + on which we call
// V V V
v->operator[](i).operator[](j).func();
}
}
}

int main(int argc, char **argv) {
QCoreApplication app(argc, argv);
QVector< QVector<MapSpace> > p1map;
p1map << QVector<MapSpace>(2);
p1map << QVector<MapSpace>(3);
someFunc(&p1map);
return 0;
}



The problem I'm facing with using your proposed solution is that this methodology of determining which map to use will be used in several functions, and most of them are being called by a class that is not aware of the 2d vectors
Not sure what you mean.

squeegedog
6th March 2014, 02:37
I found what was making everything not work using it as a pointer.


QVector< QVector<MapSpace> > p1map;
QVector< QVector<MapSpace> > p2map;
QVector< QVector<MapSpace> > p3map;
QVector< QVector<MapSpace> > p4map;
QVector< QVector<MapSpace> >* pathfix;

pathfix = &p1map

pathfix[x][y].ispassable(); //this was not working
(*pathfix)[x][y].ispassable(); //works like a charm


Thanks for all your help.


Not sure what you mean.

And I meant that in many of the functions that call to operate on the MapSpace Vector, are not aware of the Vector, so passing the Vector in as a parameter would be impossible. I was trying to keep my question as simple as possible without showing hundreds of lines of code, and somewhat over-simplified the code I gave, possibly leading to why noone discovered I was missing the (*) around my pointer variable, but all is well now.

ChrisW67
6th March 2014, 03:54
Indeed, that is a neater construct.