我想将std::cout
换行格式化,如下所示:
mycout([what type?] x, [optional args]) {
... // do some formatting on x first
std::cout << x;
}
仍然可以使用像
这样的表达语法mycout("test" << i << endl << somevar, indent)
而不是像
那样被迫更加冗长mycout(std::stringstream("test") << i ...)
我该如何实现?要制作什么类型x
?
编辑:添加了对可选参数的考虑
答案 0 :(得分:4)
使用可变参数模板参数很容易:
template <class T>
void print(T t)
{
std::cout << t;
}
template <class T, class... Args>
void print(T t, Args... args)
{
std::cout << t << std::endl;
print(args...);
}
int main()
{
std::cout << std::boolalpha;
print(3, 's', true, false);
}
输出:
3
s
true
false
答案 1 :(得分:3)
这个怎么样:
struct MyCout {};
extern MyCout myCout;
template <typename T>
MyCout& operator<< (MyCout &s, const T &x) {
//format x as you please
std::cout << x;
return s;
}
将MyCout myCout;
放入任何一个.cpp文件中。
然后您可以像这样使用myCout
:
myCout << "test" << x << std::endl;
它会调用可以进行格式化的模板operator<<
。
当然,如果您愿意,也可以为特定类型的特殊格式提供操作符的重载。
修改强>
显然(感谢@soon),要使标准操纵器工作,还需要更多的重载:
MyCout& operator<< (MyCout &s, std::ostream& (*f)(std::ostream &)) {
f(std::cout);
return s;
}
MyCout& operator<< (MyCout &s, std::ostream& (*f)(std::ios &)) {
f(std::cout);
return s;
}
MyCout& operator<< (MyCout &s, std::ostream& (*f)(std::ios_base &)) {
f(std::cout);
return s;
}
编辑2
我可能会误解你原来的要求。怎么样(加上与上面相同的操纵器重载):
struct MyCout
{
std::stringstream s;
template <typename T>
MyCout& operator << (const T &x) {
s << x;
return *this;
}
~MyCout() {
somehow_format(s);
std::cout << s.str();
}
};
int main() {
double y = 1.5;
MyCout() << "test" << y;
}
答案 2 :(得分:0)
你可以使用这种类:
#include <iostream>
using namespace std;
class CustomOut
{
public:
template<class T>
CustomOut& operator<<(const T& obj)
{
cout << " my-cout " << obj;
return *this;
}
};
int main()
{
CustomOut mycout;
mycout << "test" << 4 << "\n" << 3.4;
}
您需要更多代码才能使用std :: endl和其他仿函数,所以我在这里使用简单\ n而不是。
答案 3 :(得分:0)
答案的变体:
#include <iostream>
using namespace std;
class MyCout
{
public:
MyCout& operator()(bool indent) {
if ( indent ) cout << '\t';
return *this;
}
template<class T>
MyCout& operator<<(T t) {
cout << t;
return *this;
}
MyCout& operator<<(ostream& (*f)(ostream& o)) {
cout << f;
return *this;
};
};
int main()
{
MyCout mycout;
int x = 10;
mycout(true)<< "test" << 2 << x << endl ;
}