[英]operator << overloading in a constructor
I'm debugging a program and I would like to make printing from that pattern: 我正在调试程序,我想从该模式进行打印:
std::cout << firstVar << ", " << secondVar << ", " << thirdVar << endl ;
shorter, ie, the same thing should happen if we will write the code: 更短,也就是说,如果我们编写代码,则应该发生相同的事情:
shortPrint(std::cout) << firstVar << secondVar << thirdVar;
note: there is no limit for the variables quantity, it can be 1 and it can be 20, so that should also work: 注意:变量数量没有限制,可以为1,也可以为20,因此也可以使用:
shortPrint(std::cout) << firstVar << secondVar << thirdVar << anotherVar << oneMoreVar;
Someone told me that the easiest wat to do that is to create class that is called "shortPrint". 有人告诉我,最简单的方法就是创建一个称为“ shortPrint”的类。
Can anyone help me figuring this out? 谁能帮我解决这个问题?
For start, I would say that I only need to implement a constructor and operator << overloading, but I'm not sure how to do that exactly in that case. 首先,我会说我只需要实现一个构造函数和一个运算符<<重载,但是我不确定在那种情况下该怎么做。
Yes create a shortPrint
class with an appropriate overloaded operator. 是的,使用适当的重载运算符创建
shortPrint
类。 Something like this : 像这样的东西:
class shortPrint {
ostream &o;
public:
shortPrint(ostream &o) : o(o) {}
template <typename T> shortPrint &operator<<(const T &t) {
o << t << ',';
return *this;
}
// support for endl, which is not a value but a function (stream->stream)
shortPrint &operator<<(ostream& (*pf)(std::ostream&)) {
o << pf;
return *this;
}
};
That should work (basically). 这应该工作(基本上)。
To eliminate the problem of extra commas use this : 为了消除多余的逗号问题,请使用以下命令:
class shortPrint {
class shortPrint2{
shortPrint &s;
public:
shortPrint2(shortPrint &s) : s(s) {}
template <typename T> shortPrint2 &operator<<(const T &t) {
s.o << ',' << t ;
return *this;
}
shortPrint &operator<<(ostream& (*pf)(std::ostream&)) {
s.o << pf;
return s;
}
};
ostream &o;
shortPrint2 s2;
public:
shortPrint(ostream &o) : o(o), s2(*this) {}
template <typename T> shortPrint2 &operator<<(const T &t) {
o << t;
return s2;
}
shortPrint &operator<<(ostream& (*pf)(std::ostream&)) {
o << pf;
return *this;
}
};
You can do something like the following: 您可以执行以下操作:
class _ostream_wrap
{
public:
template <class T>
_ostream_wrap& operator << (const T & v)
{
m_ost << "[ " << v << " ]";
return (*this);
}
explicit _ostream_wrap(std::ostream & ost)
:m_ost(ost)
{}
private:
std::ostream& m_ost;
};
template <class OSTREAM>
_ostream_wrap shortPrint(OSTREAM & o)
{
return _ostream_wrap(o);
}
//...
shortPrint(std::cout) << 1 << 2;
however this implementation will not work on rvalues: 但是,此实现不适用于右值:
//you can't do something like the following:
shortPrint(MyOstream(some_args)) << 1;
This is because the class _ostream_wrap
keeps a reference to the stream and for rvalues case it needs to make a copy. 这是因为类
_ostream_wrap
保留_ostream_wrap
的引用,对于右值,它需要进行复制。 To make a copy you need to have two implementations (this would be the final version): 要制作副本,您需要两个实现(这将是最终版本):
template <class OSTREAM>
class _ostream_wrap
{
public:
template <class T>
_ostream_wrap<OSTREAM>& operator << (const T & v)
{
m_ost << "[ " << v << " ]";
return (*this);
}
public:
//the constructor is harder to write so i decided
//that for this i will keep the member public
OSTREAM m_ost;
};
template <class OSTREAM>
_ostream_wrap<OSTREAM&> shortPrint(OSTREAM & o)
{
_ostream_wrap<OSTREAM&> rvalue;
rvalue.m_ost = o;
return rvalue;
}
template <class OSTREAM>
_ostream_wrap<OSTREAM> shortPrint(const OSTREAM & o)
{
_ostream_wrap<OSTREAM> rvalue;
rvalue.m_ost = o;
return rvalue;
}
Here's something with very basic functionality: 这里有一些非常基本的功能:
#include <iostream>
struct shortPrint {
explicit shortPrint(std::ostream& os)
: strm(&os), first(true) {}
template<typename T>
shortPrint& operator<<(T&& t)
{
if (first) {
first = false;
} else {
*strm << ", ";
}
*strm << std::forward<T>(t);
return *this;
}
shortPrint& operator<<( std::ostream& (*func)(std::ostream&) )
{
*strm << func;
return *this;
}
private:
std::ostream* strm;
bool first;
};
int main()
{
int i = 3;
shortPrint(std::cout) << "1" << 2 << i << std::endl;
shortPrint(std::cout) << 4;
}
The tricky part is getting the commas to be printed correctly. 棘手的部分是使逗号正确打印。 I chose to print them before every streamed object, except before the very first one.
我选择在每个流对象之前打印它们,除了第一个对象之前。 As you can see, there's one general
operator<<
template that simply prints the comma and forwards the argument. 如您所见,有一个通用
operator<<
模板,它简单地打印逗号并转发参数。 The next problem are stream manipulators, because we don't want to print commas before them. 下一个问题是流操纵器,因为我们不想在它们之前打印逗号。 The other
operator<<
overload takes care of that. 另一个
operator<<
重载可以解决这个问题。 If you want to be more generic, there's two more you need to take care of (see no. 9 here ). 如果您想更通用一些,还需要处理两个(请参见此处的第 9号)。
Hope that helps. 希望能有所帮助。
Return the ostream from the function. 从函数返回ostream。 Something like:
就像是:
std::ostream &shortPrint(std::ostream &out) {
//whatever you need here
return out;
}
Edit: you the kind of formatting you need, you need to make a class with overloaded stream operator that returns the class. 编辑:您需要的格式化类型,您需要使用返回该类的重载流运算符来创建一个类。 But you need to keep the reference to the needed stream in the class.
但是您需要在类中保留对所需流的引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.