我正在研究一个看起来像这样的功能:
inline std::ostream& mvUp(int n,std::ostream& ss){
char u[8];
sprintf(u,"\033[%dA",n);
ss<<u;
return ss;
}
像这样使用它:
std::cout<<mvUp(1);
然而它显示错误:
std::cout<<mvUp(1);
| ^_____too few args in function call
^_______________no operator "<<" match these operands
我也试过:
std::cout<<mvUp(1,std::cout);
但还是不行。
std::cout<<mvUp(1);
^_______________no operator "<<" match these operands
现在当我尝试制作模板时,
template <int n>
inline std::ostream& mvUp(std::ostream& ss){
char u[8];
sprintf(u,"\033[%dA",n);
ss<<u;
return ss;
}
并使用它:
std::cout<<mvUp<1>
,这完全可以正常工作,但问题是模板采用const
args.
无法弄清楚我哪里错了。另外,当我不传递任何参数时,它在模板中如何工作?
现代 C++ 代码使用
std::string
和其他类。这使得实现这种过载变得微不足道。
#include <string>
#include <sstream>
inline std::string mvUp(int n) {
std::ostringstream o;
o << "\033[" << n << "A";
return o.str();
}
然后,一切都会自动工作:
std::cout<<mvUp(1);
您的
mvUp
返回 std::string
,现有的 <<
过载负责其余部分。
std::ostream& mvUp(std::ostream& ss);
std::cout << mvUp<1>
有效的事实 not C++ 函数调用语法的特性。
std::cout
的 operator<<
重载以接受像这样的单参数函数,并通过将其自身作为第一个参数传递来调用它们。
给定
std::ostream& mvUp(int n,std::ostream& ss);
,std::cout<<mvUp(1)
不起作用,因为您的函数没有一个参数。并且 std::cout << mvUp(1,std::cout);
不起作用,因为您的函数返回 std::ostream&
,无法打印。
通用的解决方案是用重载的
class
制作一个operator<<
。但是,正如另一个答案所暗示的那样,在这里你可以创建一个返回std::string
的函数,并打印它的返回值。
您正在尝试创建自定义
ostream
操纵器,类似于 std::setw()
和 <iomanip>
库中的其他操纵器。但是你所写的并不是实现它的正确方法。您的操纵器需要返回一个类型,该类型包含您要用来操纵流的信息,然后您需要重载 operator<<
以流出该类型。这将使您可以访问ostream
,然后您可以根据需要进行操作。
尝试更像这样的东西:
struct mvUpS
{
int n;
};
mvUpS mvUp(int n) {
return mvUpS{n};
}
std::ostream& operator<<(std::ostream& ss, const mvUpS &s) {
return ss << "\033[" << s.n << "A";
}
现在
std::cout << mvUp(1);
将按预期工作。