简体   繁体   中英

Type conversion in ostream& operator <<

I have a class entry and an ostream& operator << overwritten for it. I also have an auxiliary class cursor and a type conversion operator entry() . Then, in my main() function I have the following expression:

cout << data[4];

where data[4] is a cursor , but compilation fails with

error: invalid operands to binary expression

What I want is for a compiler to convert data[4] to entry and to use its << operator. Is there any way to call this ostream operator in an aforementioned way without having to add special methods to entry ?

Here are some pieces of code:

    class entry
    {
        friend class cursor;
        /*here comes some data*/

    public:    

        friend ostream& operator << (ostream& out, const entry& a);
    };

    class cursor
    {
        database* data_;
        size_t ind_;
        friend class entry;
        friend class database;

    public:
        cursor (database* a, size_t ind);
        cursor (const cursor& a);
        void operator= (const  entry x);
        void operator= (const cursor a);

        operator entry();           //type conversion
    };

and here is what I use in main():

    cout << data[4];

When you write:

class entry
{
    // ...
    friend ostream& operator << (ostream& out, const entry& a);
};

Although this declares operator<< in the enclosing scope, the name lookup rules say that name lookup in that scope does not actually find this function! (Because it has only been declared via friend ).

If a function has only been declared via friend , then the only way it can be found is via argument-dependent lookup. See this thread for more detailed explanation of the lookup rules.

The function would be found by:

entry e;
cout << e;

because ADL sees that there is an argument of type entry and so it searches functions that are associated with entry (including friends declared there).

However, cursor c; cout << c; cursor c; cout << c; does not include entry in its search list (even though a conversion from cursor to entry exists).


To fix this you need to provide a non-friend declaration of the operator, that is visible at the point of main . For example:

ostream& operator << (ostream& out, const class entry& a);

class entry
{
    // ...
    friend ostream& operator << (ostream& out, const entry& a);
};

NB. I chose to put the declaration before the class instead of after, because this is also the best way to solve the template friends problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM