ostream& 运算符中的类型转换 <<

Type conversion in ostream& operator <<

我有一个 class entry 和一个 ostream& operator << 覆盖了它。我还有辅助classcursor和类型转换operator entry()。 然后,在我的 main() 函数中,我有以下表达式:

cout << data[4];

其中 data[4]cursor,但编译失败

error: invalid operands to binary expression

我想要的是编译器将 data[4] 转换为 entry 并使用其 << 运算符。 有没有办法以上述方式调用此 ostream 运算符而不必向 entry 添加特殊方法?

这里有一些代码:

    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
    };

这是我在 main() 中使用的内容:

    cout << data[4];

当你写:

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

虽然这在封闭范围内声明了 operator<<,但名称查找规则表明在该范围内进行名称查找实际上并没有找到该函数! (因为它只通过 friend 声明过)。

如果函数仅通过 friend 声明,那么找到它的唯一方法是通过参数相关查找。有关查找规则的更详细说明,请参阅 this thread

该函数将通过以下方式找到:

entry e;
cout << e;

因为 ADL 看到有一个 entry 类型的参数,所以它搜索与 entry 关联的函数(包括在那里声明的朋友)。

但是,cursor c; cout << c; 的搜索列表中不包含 entry(即使存在从 cursorentry 的转换)。


要解决此问题,您需要提供运算符的非友元声明,该声明在 main 处可见。例如:

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

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

注意。我选择把声明放在class之前,而不是之后,因为这也是解决模板友问题的最好方法。