0

So I found this code on here that I'm working with:

#include <iostream>
#include <cstdlib>
#include <vector>

using namespace std;

struct Something{
    int x;
    int y;
};

int main()
{
    vector <Something> v;
    int x, y;
    cin >> x >> y;

    Something temp;
    temp.x = x;
    temp.y = y;
    v.push_back(temp);

    for (size_t i = 0; i < v.size(); i++)
    {
        cout << v[i] << endl; // Error: No operator "<<" matches these operands. Operand types are std::ostream << Something
    }
}

Basically, I'm trying to get multiple ints into one vector index. cout is not working when I try to print the contents of the vector.

First of all, am I even doing this multiple int thing right? I'm relatively new to C++.

And if I am doing this right, any ideas as to why cout isn't working? I also tried v.push_back({x,y}) and that didn't work. Any idea what is going on with cout? Thanks a lot.


EDIT: Thank you very much so far. I just have one more question. If I were to modify my code to take multiple inputs and later wanted everything in the vector sorted according to "y" from largest to smallest.

Example (Original Vector Contents (x,y))

12 4 1 2 4 10 1 1 1 2

Sorted according to 'y' (largest to smallest)

4 10 12 4 1 2 1 2 1 1

I know how to do a regular sort but not one according to the second number (y). How do I do that? Thanks a lot.

G_Man
  • 169
  • 1
  • 2
  • 12

4 Answers4

2

Just like the error says, there's no overloaded operator<< function declared for your structure.

There are three possible solutions: The first is to output each member of the structure, like

std::cout << v[i].x << ' ' << v[i].y << '\n';

The other is to create a function that does the above, either as a member function or as a non-member function.

The third solution is to create an overloaded operator<< function for the structure:

std::ostream& operator<<(std::ostream& os, Something const& something)
{
    return os << something.x << ' ' something.y;
}

I recommend you find a good beginners book on C++ and read the chapters about output, structures and classes, and operators and operator overloading.

Community
  • 1
  • 1
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Thank you very much so far. I just have one more question however, it doesn't look good when I write it here (formatting) so I've put it in my question as an edit. Thanks again. – G_Man May 06 '16 at 06:38
  • @G_Man Read about [`std::sort`](http://en.cppreference.com/w/cpp/algorithm/sort). It can take a comparison function argument, that can compare anything you want. Or you could specialize [`std::greater`](http://en.cppreference.com/w/cpp/utility/functional/greater) for your structure and use `std::greater` as the comparator when calling `std::sort`. – Some programmer dude May 06 '16 at 06:44
0

cout does not work for your struct because it was not defined to do so. I think you can find the answer here. Overloading operators in typedef structs (c++)

Community
  • 1
  • 1
Yumi F
  • 21
  • 4
0

operator<< is not automatically available between cout and objects of user defined classes. They need to be defined before you can be used.

In your case, you need to define a friend function inside the struct definition's body

friend std::ostream& operator<<(std::ostream& out, Something const& s);

to be able to use

cout << v[i] << endl; 

The implementation of the function is not too difficult.

std::ostream& operator<<(std::ostream& out, Something const& s)
{
    return out << s.x << " " << s.y;
}

If you want be able to use:

Something s;
std::cin >> s;

you'll have to define a similar function.

someOne
  • 1,975
  • 2
  • 14
  • 20
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Thank you very much so far. I just have one more question however, it doesn't look good when I write it here (formatting) so I've put it in my question as an edit. Thanks again. – G_Man May 06 '16 at 06:42
0

The problem is that << is an operator. It is defined on std::cout (which is an std::ostream) for a number of types. For example, it's defined for int, which is why this works:

std::cout << 3;

However, you are trying to apply the operator<< to your own Something class, but it has no such operator definition. You can add it like this:

struct Something {
    // Other stuff here
    friend std::ostream& operator<<(std::ostream& os, Something const& smth) ;
};

std::ostream& operator<<(std::ostream& os, Something const& smth) {
    os << "(" << smth.x << ", " << smth.y << ")";
    return os;
}

Then your code should work. Overloading this operator is actually more difficult than overloading others because you need to understand what friend does.

Edit:

friend is actually not needed in your case, because x and y are public. But in the general case you need it to be able to print private members of your class.

Edit 2:

To make the previous edit clear, you can omit the entire in-struct declaration of the operator, since it will be looked up globally. You only need it (and then it needs to be friendly) if the operator needs to read private members.

someOne
  • 1,975
  • 2
  • 14
  • 20
Stjepan Bakrac
  • 1,047
  • 11
  • 18
  • Actually, when the compiler sees an expression like `cout << s`, it invokes _global function_ `operator<<`, so you do need to declare it as a `friend` inside the class of `Something` :) – someOne May 06 '16 at 06:09
  • Thank you all very much so far. I just have one more question however, it doesn't look good when I write it here (formatting) so I've put it in my question as an edit. Thanks again. – G_Man May 06 '16 at 06:43
  • The `friend` declarations do have the right to access the non-public (and public) members of the class; However, you declare the method as a `friend` because it needs to be a function (which needs to be defined outside the class's scope) and yet has the access to the members since the compiler invokes it as a _global function_ :) – someOne May 06 '16 at 06:47
  • @someOne My second edit was to make it clear that you do not need to declare it inside of the class *at all* if you don't need private members. It can be just defined outside of the function. I.e. this works: http://ideone.com/cTOE48 – Stjepan Bakrac May 06 '16 at 18:19