我正在调试程序,我想从该模式进行打印:
std::cout << firstVar << ", " << secondVar << ", " << thirdVar << endl ;
更短,即如果我们编写代码,就会发生同样的事情:
shortPrint(std::cout) << firstVar << secondVar << thirdVar;
注意:变量数量没有限制,它可以是1,它可以是20,所以这也应该有效:
shortPrint(std::cout) << firstVar << secondVar << thirdVar << anotherVar << oneMoreVar;
有人告诉我,最容易做到的就是创建一个名为“shortPrint”的课程。
任何人都可以帮我解决这个问题吗?
首先,我想说我只需要实现构造函数和运算符&lt;&lt;重载,但我不确定在那种情况下该怎么做。
答案 0 :(得分:6)
是使用适当的重载运算符创建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;
}
};
答案 1 :(得分:2)
您可以执行以下操作:
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;
但是这个实现不适用于rvalues:
//you can't do something like the following:
shortPrint(MyOstream(some_args)) << 1;
这是因为类_ostream_wrap
保留了对流的引用,并且对于需要进行复制的rvalues情况。要制作副本,您需要有两个实现(这将是最终版本):
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;
}
答案 2 :(得分:1)
这是具有非常基本功能的东西:
#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节here)。
希望有所帮助。
答案 3 :(得分:0)
从函数中返回ostream。类似的东西:
std::ostream &shortPrint(std::ostream &out) {
//whatever you need here
return out;
}
编辑:你需要的那种格式化,你需要创建一个带有重载流操作符的类来返回类。但是你需要保持对类中所需流的引用。