24

I have a question about the new shortcut way of defining vectors in c++11. Suppose I have the following class

struct Tester{

  vector< vector<int> > data;

  Tester(){
    data = vector< vector<int> >();
  }

  void add(vector<int> datum){
    data.push_back(datum);
  }

};

Then, the following works as expected:

int main(){
    Tester test = Tester();
    vector<int> datum = vector<int>{1,2,3};
    test.add(datum);
}

but this doesn't:

int main(){
    Tester test = Tester();
    test.add(vector<int>{1,2,3});
}

Can someone please explain the difference to me? How can I do the shortcut I attempt in the second main()?

Fred
  • 4,894
  • 1
  • 31
  • 48
andyInCambridge
  • 1,215
  • 2
  • 13
  • 27
  • 1
    C++11 allows you to leave no space between template brackets: `vector>` is legal. – zneak Dec 20 '12 at 15:51
  • You should also post the error you get with your second attempt. Off my head and without a C++11 compiler at hand, I'd think it would work with either just the initializer list (`test.add({1,2,3})`) or with parentheses arount it (`test.add(vector({1,2,3}))`). – zneak Dec 20 '12 at 15:54
  • 6
    `data = vector< vector >();` is totally superfluous and might point out a fundamental misunderstanding in C++ constructors and initialization. – PlasmaHH Dec 20 '12 at 15:56
  • 1
    Not related to the error, but you could avoid a potential copy in the `add` method by using a reference: `void add(const vector& datum)` – juanchopanza Dec 20 '12 at 16:37

2 Answers2

28

Your code seems to be okay but the compiler you're using is not (which seems to be old).

By the way, you're doing too much.

This is should be enough:

vector<int> datum{1,2,3}; //initialization

test.add({1,2,3}); //create vector<int> on the fly and pass it to add()

Don't forget to update your compiler.

Also, the line data = vector< vector<int> >(); is also too much. It is not needed. The vector is constructed automatically, which means you can leave the constructor of your class empty, or don't have it at all, as it doesn't do anything anyway.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Thanks! Those are nice shortcuts. I agree the constructor isn't needed -- I was just being explicit. Turns out my original code does work; I must have not saved an emacs buffer or something. – andyInCambridge Dec 20 '12 at 16:10
2

If you want to avoid data copying:

#include <vector>
#include <iostream>

using namespace std;

struct Tester
{
    vector< vector<int> > data;

    Tester()
    {
        data = vector< vector<int> >();
    }

    void add(vector<int> && datum)
    {
        data.push_back(std::move(datum));
    }

};


int main()
{
    Tester test = Tester();
    test.add(vector<int>{1,2,3});

    for(const auto &v : test.data[0])
        std::cout << v << std::endl;
}
foxfireee
  • 180
  • 1
  • 7