5
votes

I created a struct type which contains two variables. I use this data type within a vector, that is again stored in a map, as following:

struct A {
    int x;
    Y y;
    A() {};
    A(int _x, Y _y) { x=_x, y=_y; };
};

typedef std::vector<A> LA;
typedef std::map<uint,LA> MB;

MB b;

When I try to use an iterator, such as

std::vector<LA>::iterator it = b[x].begin();

the compiler gives this error:

error: no viable conversion from '__wrap_iter< A *>' to '__wrap_iter< std::__1::vector < A, std::__1::allocator< A> > *>' std::vector< LA>::iterator it = b[x].begin();

candidate constructor (the implicit copy constructor) not viable: no known conversion from 'iterator' (aka '__wrap_iter< pointer>') to 'const std::__1::__wrap_iter< std::__1::vector< A, > std::__1::allocator< A> > *> &' for 1st argument class__wrap_iter

candidate constructor (the implicit move constructor) not viable: no known conversion from 'iterator' (aka > '__wrap_iter< pointer>') to 'std::__1::__wrap_iter< std::__1::vector< A, > std::__1::allocator< A> > *> &&' for 1st argument class__wrap_iter

candidate template ignored: disabled by 'enable_if'

What is the reason for this error? Although I tried several things like operator overloading, I could not solve this. Any help is appreciated.

3
Suggestion: LA::iterator it = b[x].begin(); – paulsm4
@paulsm4: I said this already. In the answer section. Where it belongs! – Lightness Races in Orbit

3 Answers

8
votes

You don't have a vector of LA; you have a vector of A. So:

std::vector<A>::iterator it = b[x].begin();

or:

LA::iterator it = b[x].begin();

Looks like a simple typo to me?

(Not very surprising given these terrible type names...)

2
votes

The others here have already answered why the compiler complained.

So I will not repeat that but give an alternative "fix". It'll only work if you can use C++11 syntax in your project/environment.

If so, the iterator can be created as follows:

auto it = b[x].begin();

This is not as explicit as when specifiying the exact type for it, but at least it's less typing. Note that this will only work in C++11 or higher, and you will need to compile with -std=c++11 in g++. Visual Studio 2013 and higher will understand that syntax out of the box.

1
votes

The part that goes inside the <> in a std::vector<> is the type of the object that the vector is going to hold, e.g., std::vector<int> or std::vector<double>. In your case the type of object in the vector is A. So you should write

std::vector<A>::iterator it = b[x].begin();

or using your typedef,

LA::iterator is = b[x].begin();