在ostream和operator <<中键入转换

tas*_*kie 2 c++ operator-overloading friend-function argument-dependent-lookup

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

cout << data[4];
Run Code Online (Sandbox Code Playgroud)

这里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);
    };
Run Code Online (Sandbox Code Playgroud)

    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
    };
Run Code Online (Sandbox Code Playgroud)

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

    cout << data[4];
Run Code Online (Sandbox Code Playgroud)

M.M*_*M.M 6

当你写:

class entry
{
    // ...
    friend ostream& operator << (ostream& out, const entry& a);
};
Run Code Online (Sandbox Code Playgroud)

虽然这operator<<在封闭范围内声明,但名称查找规则表明该范围内的名称查找实际上并未找到此函数!(因为它只是通过声明friend).

如果一个函数只是通过声明friend,那么它唯一可以找到的方法是通过参数依赖查找.有关查找规则的更详细说明,请参阅此主题.

该功能将通过以下方式找到:

entry e;
cout << e;
Run Code Online (Sandbox Code Playgroud)

因为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);
};
Run Code Online (Sandbox Code Playgroud)

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