1

For testing purposes, I'm running the following code through a for loop. Only the first three keys actually exist, and "Record found" is displayed as expected, along with the key, retrieved from findVertex->first.

  • My question is, how would I be able to access the second value being pointed to?

findVertex->secondseems obvious, but does not work, as the second value is an object I created, the declaration of which is given below the code, if it would be of any use.

for(int i = 0; i<10; i++)
    {
     map<int, vector<Vertex> >::const_iterator findVertex = vertexMap.find(i);

     if(findVertex != vertexMap.end())
      {
          cout<<"\nRecord found: ";
          cout<<findVertex->first;
          cout<<findVertex->second; //does not work
      }
     else
         cout<<"\nRecord not found";
}

Class code:

class Vertex
{
    private:
        int currentIndex;
        double xPoint, yPoint, zPoint;
        vector<double> attributes;

    public:
        friend istream& operator>>(istream&, Vertex &);
        friend ostream& operator<<(ostream&, Vertex &);
};

Thanks

Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • Provide an operator: `std::ostream& operator << (std::ostream&, const std::vector&)` –  May 19 '15 at 16:39

2 Answers2

2

Your map is of the type

map<int, vector<Vertex>>

This means first is an int, and second is vector<Vertex>.

While you have defined operator<< for Vertex, there is no such function for vector<Vertex>. You'd have iterate through your vector, if you have access to C++11 you can use something like

 if(findVertex != vertexMap.end())
 {
     cout << "\nRecord found: ";
     cout << findVertex->first << '\n';
     for (auto const& vertex : findVertex->second)
     {
         cout << vertex << '\n';
     }
 }

If you don't have access to C++11 you can do the same idea manually

 if(findVertex != vertexMap.end())
 {
     cout << "\nRecord found: ";
     cout << findVertex->first << '\n';
     for (vector<Vertex>::const_iterator itVertex = findVertex->second.cbegin();
          itVertex != findVertex->second.cend();
          ++itVertex)
     {
         Vertex const& vertex = *itVertex;
         cout << vertex << '\n';
     }
 }
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • Thanks for this. I don't have access to C++11 and used the manual version. However, I was presented with this error: `error: no match for 'operator=' (operand types are 'std::vector::iterator {aka __gnu_cxx::__normal_iterator >}' and 'std::vector::const_iterator {aka __gnu_cxx::__normal_iterator >}')|` – Collin Oladimeji May 19 '15 at 16:50
  • @CollinOladimeji Try the edited code now. I changed to `::const_iterator` and use `cbegin()` and `cend()`. – Cory Kramer May 19 '15 at 16:51
  • @Collin Oladimeji See my answer.:) – Vlad from Moscow May 19 '15 at 16:59
  • @Cyber Apparently, `error: 'const class std::vector' has no member named 'cbegin'|`. Could I be missing an include? – Collin Oladimeji May 19 '15 at 17:00
1

First of all you may not use const_iterator

map<int, vector<Vertex> >::const_iterator findVertex = vertexMap.find(i);

to display Vertex because you declared operator << with second parameter as a non-const reference

friend ostream& operator<<(ostream&, Vertex &); 
                                     ^^^^^^^^

You should declare it like

friend ostream& operator<<(ostream&, const Vertex &);
                                     ^^^^^

Otherwise change the above statement to the following

map<int, vector<Vertex> >::iterator findVertex = vertexMap.find(i);
                           ^^^^^^^^ 

And change this statement

cout<<findVertex->second; //does not work

to the following code snippet

for ( Vertex &v : findVertex->second ) cout << v << endl;

If you will modify the operator specyfying qualifier const for the second parameter then you can write

map<int, vector<Vertex> >::const_iterator findVertex = vertexMap.find(i);
                           ^^^^^^^^^^^^^^
//...

for ( const Vertex &v : findVertex->second ) cout << v << endl;
      ^^^^^

Or instead of the range based for statement you can use an ordinary loop as for example

for ( std::vector<Vertex>::size_type i = 0; i < findVertex->second.size(); i++ )
{
    std::cout << findVertex->second[i] << std::endl;
}

or

for ( std::vector<Vertex>::iterator it = findVertex->second.begin(); 
      it != findVertex->second.end(); 
      ++it )
{
    std::cout << *it << std::endl;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335