[英]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.