0

I have a class that declares a vector of vectors in a .h header file as follows:

#include <vector>
    
class Mapper {
    public:
        ...
        Mapper(const uint num_rows, const uint num_cols, const double initial_val);
        ...
    private:
        ...
        std::vector<std::vector<double>> grid_map_;
        ...
};

And the definition of the Mapper class is implemented in a corresponding .cpp. However, I'm trying to figure out if there's a way to initialize the grid_map_ vector of vectors in the Mapper constructor using the assignment operator notation similar to what's shown below:

Mapper::Mapper(const uint num_rows, const uint num_cols, const double initial_val) {
    ...
    grid_map_ = std::vector<vector<double>>(num_rows, num_cols, initial_val);
    ...
}

I know I can initialize it as follows,

std::vector<std::vector<double>> vec(num_rows, std::vector<double>(num_cols, initial_val));
grid_map_ = vec;

or I could also use an initializer list, however, I'm trying to avoid those two methods. Is such a thing possible?

What I'm trying to do is similar to declaring a custom type in the .h, and then instantiating it in the constructor using assignment operator notation. For example in the header you'd have:

Object object_;

and then in the .cpp file you'd have:

object_ = Object();

Is initializing a vector of vectors in this way possible?

indigoblue
  • 453
  • 6
  • 13
  • 2
    You know all the pieces. Just combine them: `grid_map_ = std::vector>(num_rows, std::vector(num_cols, initial_val));` Better still, initialize `grid_map_` in constructor initializer list. – Igor Tandetnik Dec 13 '20 at 00:33
  • 1
    Don't use nested vectors for square data at scale. They have loads of overhead and you don't need them. Make yourself a nice vector of _num_rows × num_cols_ `double`s instead. As a bonus, you probably already know the quick, easy way to initialise one of those! – Asteroids With Wings Dec 13 '20 at 00:34
  • 1
    By the way, as it sounds like you haven't heard of it, you should be [initialising members in the member initialiser list](https://stackoverflow.com/q/1711990/4386278) as much as possible. – Asteroids With Wings Dec 13 '20 at 00:37
  • Thanks for the answers @AsteroidsWithWings, I mentioned an initializer in my post, but I'm trying to avoid it simply for aesthetic reasons (even though it can be more efficient afaik). – indigoblue Dec 13 '20 at 00:41
  • @AsteroidsWithWings, do you have a source showing the overhead of using nested vectors, I'd be interested to read more. – indigoblue Dec 13 '20 at 01:57
  • 1
    First of all you have many allocations instead of one big allocation. Second: Your data will not be in one continuous chunk of memory. Instead it will be scattered which gives you worse cache locality. Third: Every time you access an element, the processor will have to dereference two pointers instead of one (so-called pointer chasing) which should take longer than just calculating the linear index like ```grid_map_[row * num_cols + col]```. This is called lexic indexing. – paleonix Dec 13 '20 at 02:36
  • 1
    Frustratingly it is much easier to find sources about working with nested vectors than finding sources about them being a performance sin when trying to implement a matrix. But if you have an idea about the implementation of ```vector``` and about modern processor architecture, it is very clear that nesting them is bad. – paleonix Dec 13 '20 at 02:55
  • @indigoblue What you showed in your post is not initialization. – Asteroids With Wings Dec 13 '20 at 20:16
  • What's better: a wallet that contains 100 wallets that each have $1 in them, or a wallet that has $100 in it? – Asteroids With Wings Dec 13 '20 at 20:17

0 Answers0