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

时间:2016-03-17 22:35:12

标签: c++ operator-overloading argument-dependent-lookup friend-function

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

cout << data[4];

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

  

错误:二进制表达式的操作数无效

我想要的是编译器将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];

1 个答案:

答案 0 :(得分:6)

当你写:

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

NB。我选择将声明放在课前而不是之后,因为这也是解决模板朋友问题的最好方法。