我有一个课程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];
答案 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
(即使存在从cursor
到entry
的转换)。
要解决此问题,您需要提供操作符的非朋友声明,该声明在main
处可见。例如:
ostream& operator << (ostream& out, const class entry& a);
class entry
{
// ...
friend ostream& operator << (ostream& out, const entry& a);
};
NB。我选择将声明放在课前而不是之后,因为这也是解决模板朋友问题的最好方法。