0

Well I am questioning myself if there is a way to pass a vector directly in a parameter, with that I mean, like this:

int xPOS = 5, yPOS = 6, zPOS = 2;
//^this is actually a struct but 
//I simplified the code to this

std::vector <std::vector<int>>  NodePoints;
NodePoints.push_back(
    std::vector<int> {xPOS,yPOS,zPOS}
);

This code ofcourse gives an error; typename not allowed, and expected a ')'

I would have used a struct, but I have to pass the data to a Abstract Virtual Machine where I need to access the node positions as Array[index][index] like:

public GPS_WhenRouteIsCalculated(...)
{
    for(new i = 0; i < amount_of_nodes; ++i)
    {
        printf("Point(%d)=NodeID(%d), Position(X;Y;Z):{%f;%f;%f}",i,node_id_array[i],NodePosition[i][0],NodePosition[i][1],NodePosition[i][2]); 
    }
    return 1;
}

Ofcourse I could do it like this:

std::vector <std::vector<int>>  NodePoints;//global
std::vector<int> x;//local
x.push_back(xPOS);
x.push_back(yPOS);
x.push_back(zPOS);
NodePoints.push_back(x);

or this:

std::vector <std::vector<int>>  NodePoints;//global
std::vector<int> x;//global
x.push_back(xPOS);
x.push_back(yPOS);
x.push_back(zPOS);
NodePoints.push_back(x);
x.clear()

but then I'm wondering which of the two would be faster/more efficient/better? Or is there a way to get my initial code working (first snippet)?

3 Answers3

2

Use C++11, or something from boost for this (also you can use simple v.push_back({1,2,3}), vector will be constructed from initializer_list).

http://liveworkspace.org/code/m4kRJ$0

You can use boost::assign as well, if you have no C++11.

#include <vector>
#include <boost/assign/list_of.hpp>

using namespace boost::assign;

int main()
{
   std::vector<std::vector<int>> v;
   v.push_back(list_of(1)(2)(3));
}

http://liveworkspace.org/code/m4kRJ$5

and of course you can use old variant

int ptr[1,2,3];
v.push_back(std::vector<int>(ptr, ptr + sizeof(ptr) / sizeof(*ptr));
ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • visual studio 2012 hates me . v.push_back({0,1,2}); won't compile -.-' –  Jan 25 '13 at 10:21
1

If you don't have access to either Boost or C++11 then you could consider quite a simple solution based around a class. By wrapping a vector to store your three points within a class with some simple access controls, you can create the flexibility you need. First create the class:

class NodePoint
{
public:
    NodePoint( int a, int b, int c )
    {
        dim_.push_back( a );
        dim_.push_back( b );
        dim_.push_back( c );
    }

    int& operator[]( size_t i ){ return dim_[i]; }

private:
    vector<int> dim_;
};

The important thing here is to encapsulate the vector as an aggregate of the object. The NodePoint can only be initialised by providing the three points. I've also provided operator[] to allow indexed access to the object. It can be used as follows:

NodePoint a(5, 6, 2);
cout << a[0] << " " << a[1] << " " << a[2] << endl;

Which prints:

5 6 2

Note that this will of course throw if an attempt is made to access an out of bounds index point but that's still better than a fixed array which would most likely seg fault. I don't see this as a perfect solution but it should get you reasonably safely to where you want to be.

Component 10
  • 10,247
  • 7
  • 47
  • 64
1

If your main goal is to avoid unnecessary copies of vector<> then here how you should deal with it.

C++03

Insert an empty vector into the nested vector (e.g. Nodepoints) and then use std::swap() or std::vector::swap() upon it.

NodePoints.push_back(std::vector<int>());  // add an empty vector
std::swap(x, NodePoints.back()); // swaps contents of `x` and last element of `NodePoints`

So after the swap(), the contents of x will be transferred to NodePoints.back() without any copying.

C++11

Use std::move() to avoid extra copies

NodePoints.push_back(std::move(x));  // #include<utility>

Here is the explanation of std::move and here is an example.

Both of the above solutions have somewhat similar effect.

Community
  • 1
  • 1
iammilind
  • 68,093
  • 33
  • 169
  • 336