Overloading the <<

Hello. This chunk of code reports an error:
1
2
3
4
5
6
7
In function 'std::ostream& operator<<(std::ostream&, const zv::date&)':
error: 'int zv::date::day' is private
error: within this context
error: 'int zv::date::month' is private
error: within this context
error: 'int zv::date::year' is private
error: within this context


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
namespace zv
{
    class date
    {
    private:
        int day, month, year;
    public:
        //
        friend ostream &operator << (ostream &cout, const date &a);
    };
}

ostream &operator << (ostream &cout, const zv::date &a)
{
    return cout << a.day << '/' << a.month << '/' << a.year;
}


I just can't identify the error. Thank you in advance.
change the name of your ostream & to something else like "out"

1
2
3
4
ostream &operator << (ostream &out, const zv::date &a)
{
    return out << a.day << '/' << a.month << '/' << a.year;
}


one reason not to use using namespace std;


if you don't use using namespace std;, then you can name it "cout"
1
2
3
4
5
6
7
8
9
//class zv::date
//..
friend std::ostream &operator << (std::ostream &cout, const date &a);
//end zv::date

std::ostream &operator << (std::ostream &cout, const zv::date &a)
{
    return cout << a.day << '/' << a.month << '/' << a.year;
}
Last edited on
I used
 
using std::ostream;

on the top.

I tried what you said and the result is same...
Last edited on
You declare your operator<< inside the zv namespace, so the operator<< you define must be a member of it:

1
2
3
4
ostream & zv::operator << (ostream &out, const zv::date &a)
{
    return out << a.day << '/' << a.month << '/' << a.year;
}


To keep operator<< in the global namespace you'd need to do something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
namespace zv {
    class date;
}

ostream& operator<< (ostream&, const zv::date&);

namespace zv
{
    class date
    {
    private:
        int day, month, year;
    public:
        //
        friend ostream & ::operator << (ostream &out, const date &a);
    };
}

ostream & operator << (ostream &out, const zv::date &a)
{
    return out << a.day << '/' << a.month << '/' << a.year;
}


You don't really lose anything by having it in the zv namespace. You don't need to qualify the operator to use it due to the way name lookups happen, so keeping it in the zv namespace is a cleaner solution.
Last edited on
um... You also need to wrap namespace zv { ... } around your operator<< implementation...

like this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
namespace zv
{
    class date
    {
    private:
        int day, month, year;
    public:
        //
        friend ostream &operator << (ostream &cout, const date &a);
    };
    
    ostream &operator << (ostream &cout, const zv::date &a)
    {
        return cout << a.day << '/' << a.month << '/' << a.year;
    }
}



or this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
namespace zv
{
    class date
    {
    private:
        int day, month, year;
    public:
        //
        friend ostream &operator << (ostream &cout, const date &a);
    };
}

namespace zv
{
    ostream &operator << (ostream &cout, const zv::date &a)
    {
        return cout << a.day << '/' << a.month << '/' << a.year;
    }
}



also provide your class constructor before using the << operator or it will output junks.
Last edited on
This

produces
 
error: 'std::ostream& zv::operator<<(std::ostream&, const zv::date&)' should have been declared inside 'zv'


And the second is working... Constructor is there btw (removed from post to reduce size)
1
2
3
4
5
6
7
namespace zv
{
    ostream &operator << (ostream &cout, const zv::date &a)
    {
        return cout << a.day << '/' << a.month << '/' << a.year;
    }
}


Thanks.
Maybe you mistype std::ostream& zv::operator<<(std::ostream& cout, const zv::date& a) in the first one. They (the first and second one) are the same.

Here is the test run: http://ideone.com/BbuJWa
Topic archived. No new replies allowed.