0
votes

I have written a code which has to iterate through a vector and print its contents. I am getting an error:

dfs.cpp:45:16: error: no match for ‘operator*’ (operand type is ‘const traits’) std::cout << *c << ' '; dfs.cpp:44:15: error: cannot bind ‘std::ostream {aka std::basic_ostream}’ lvalue to ‘std::basic_ostream&&’ std::cout<<*v<

However, the iteration works for a vector of type char

#include<iostream>
#include<list>
#include<vector>
#include<stdio.h>

using namespace std;

struct traits
{
    int x;
    bool visit;
    std::list<int> friends;
};

int main()
{
    cout << "Enter the number of employees: " << endl;
    int noOfEmployees, noOfFriends;
    cin>>noOfEmployees;
    std::vector<traits> employees;
    int i = 0; int j;
    while(noOfEmployees--){
        traits v;
        v.x = i;
        cout << "Enter the no of friends: " << endl;
        cin >> noOfFriends;
        while(noOfFriends--){
            cin>>j;
            v.friends.push_back(j);
        }
        v.visit = false;
        employees.push_back(v);
    }

    std::vector<char> path;
    path.push_back('a');
    path.push_back('l');
    path.push_back('i');
    path.push_back('a');
    for (std::vector<char>::const_iterator i = path.begin(); i != path.end(); ++i){
        std::cout << *i << ' ';
    }
    for(std::vector<traits>::iterator v = employees.begin(); v != employees.end(); ++v){
        std::cout<<*v<<endl;
    }
}

I have seen few answers but I want to do this without operator overloading, what would be the correct or more C++-nic way?

2
You need to overload operator<< for traits, or print out the content of traits by yourself. - songyuanyao
Why would there exist a built-in operator<< for a type you just created? char is part of the language, of course printing it would be supported out of the box. - StoryTeller - Unslander Monica
One does not exist for the standard containers, you have to write an overload for yourself. - Francis Cugler
It doesn't make much sense to give code that works and provide an error message for code that you do not show. Please provide an minimal reproducible example. Thanks. - Werner Henze

2 Answers

3
votes

The error your getting is telling you that the ostream operator doesn't have a rule to apply to objects of type trait. The most "C++nic" way to do this would be to overload the << operator, but you've said that you don't want to do that.

Given that constraint, your can translate the traits item into something the ostream operator supports. A reasonable way to do this would be with a namespace level, non-member function

std::string to_string(const traits& t) {
/// Code to generate a string representation of your traits object
}
for (const auto emp& : employees){
    std::cout<< to_string(emp) << ' ';
}

If I saw code like this in production I would expect the author had a reason not to use the more canonical operator overload, and I'd be disappointed if they did not.

1
votes

When using the iostream operators << & >> for istream and ostream either it be for cout and cin or ifstream, ofstream or fstream objects think of it in the manner of the compiler or one who is writing the compiler...

These are template types. A user will create a template with a various number of types that could be built in or custom user defined. To give this kind of power to the user how would the compiler know if the ostream in your case that will be using a list is a list<int>, list<float>, list<yourType>? So you have to create the overload yourself for all the types that you want to support the operator>>() and operator<<(). And as user Spacemoose beat me to it; you would have to convert the underlying type via stand a lone function to a type that already works with the operators.