我有一个类“标记流”,基本上打算像'cout'一样工作 . 接下来的两个函数是在课外 . 这是有效的部分 .
class stampstream: public std::ostream
{
//code
stampstream& operator<<(stampstream& (*x)(void))
{
//code
}
//code
};
stampstream& endr()
{
//nocode
}
stampstream& (*endrow)(void)=endr;
主要:
stampstream s;
s << "teststring1" << endrow;
请注意,“endrow”基本上是“endl” . 这部分工作得很好,编译和执行正确的输出 . 现在,我正在尝试用另一个可能的row(int)函数重载<< . 这是不起作用的部分 . 同样,它是上述同一类的一部分,以下两个函数在类之外 .
class stampstream: public std::ostream
{
//code
stampstream& operator<<(stampstream& (*r)(int y))
{
//code
}
//code
};
stampstream& ro(int y)
{
//nocode
}
stampstream& (*row)(int)=ro;
主要:
s << "teststring2" << row(5);
这是我得到的错误:
error: invalid user-defined conversion from ‘stampstream’ to ‘stampstream& (*)(int)’ [-fpermissive]
排怎么办?
2 回答
问题在于
函数调用的优先级高于
<<
,因此这将调用函数row
指向,然后尝试将其返回值(stampstream &
)传递给operator<<
.你想要的是什么
这不会调用函数,而是将指针传递给
operator<<
. 在该函数内部,当您想要调用x
时,您需要提供参数 .这听起来像你要做的是有一个函数
row
,它创建一个仿函数对象,然后你可以传递给operator<<
. 您可以使用lambda在C 11中执行此操作:您可以称之为:
首先调用
row
,它构造一个lambda并返回它(但还没有运行代码) . 函数传递给operator<<
,当该函数调用r
时,它将调用lambda中的代码(可以引用x
param,它被值绑定,因此被复制到lambda中 . )由于Chris已经回答了您的问题,我想建议您替换当前的方法:
您的
stampstream
类应该使用专门的std::streambuf
来写出overflow()
内的图章 . 没有必要扩展std::ostream
并重新实现输入运算符 . 有关如何执行此操作的示例,see this thread .你似乎正在使用
endrow
和row
之类的操纵者 . 对于不在调用站点处接受参数的操纵器,已存在运算符重载 . 您可以endrow
获取并返回std::ostream&
类型的对象 . 对于row
,您可以让它返回一个重载插入器的类,以允许您想要的语法:现在
s << endrow
和s << row(5)
无需向stampstream
类添加任何内容即可使用 .