[英]operator << overloading in a constructor
我正在调试程序,我想从该模式进行打印:
std::cout << firstVar << ", " << secondVar << ", " << thirdVar << endl ;
更短,也就是说,如果我们编写代码,则应该发生相同的事情:
shortPrint(std::cout) << firstVar << secondVar << thirdVar;
注意:变量数量没有限制,可以为1,也可以为20,因此也可以使用:
shortPrint(std::cout) << firstVar << secondVar << thirdVar << anotherVar << oneMoreVar;
有人告诉我,最简单的方法就是创建一个称为“ shortPrint”的类。
谁能帮我解决这个问题?
首先,我会说我只需要实现一个构造函数和一个运算符<<重载,但是我不确定在那种情况下该怎么做。
是的,使用适当的重载运算符创建shortPrint
类。 像这样的东西:
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;
}
};
这应该工作(基本上)。
为了消除多余的逗号问题,请使用以下命令:
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;
}
};
您可以执行以下操作:
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;
但是,此实现不适用于右值:
//you can't do something like the following:
shortPrint(MyOstream(some_args)) << 1;
这是因为类_ostream_wrap
保留_ostream_wrap
的引用,对于右值,它需要进行复制。 要制作副本,您需要两个实现(这将是最终版本):
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;
}
这里有一些非常基本的功能:
#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;
}
棘手的部分是使逗号正确打印。 我选择在每个流对象之前打印它们,除了第一个对象之前。 如您所见,有一个通用operator<<
模板,它简单地打印逗号并转发参数。 下一个问题是流操纵器,因为我们不想在它们之前打印逗号。 另一个operator<<
重载可以解决这个问题。 如果您想更通用一些,还需要处理两个(请参见此处的第 9号)。
希望能有所帮助。
从函数返回ostream。 就像是:
std::ostream &shortPrint(std::ostream &out) {
//whatever you need here
return out;
}
编辑:您需要的格式化类型,您需要使用返回该类的重载流运算符来创建一个类。 但是您需要在类中保留对所需流的引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.