Fai in modo che una classe C ++ si comporti come un ostream personalizzato, sstream
-
03-07-2019 - |
Domanda
Ho una classe C ++ MyObject
e voglio essere in grado di alimentare questi dati come farei con un osstream (ma a differenza di un flusso diretto, i dati in arrivo devono essere formattati in modo speciale). Non riesco a capire come sovraccaricare un operatore affinché MyObject possa mangiare l'input che gli è stato dato.
class MyObject {
public:
ostringstream s;
FEEDME
};
int main() {
MyObject obj;
obj.FEEDME << "Hello" << 12345;
// I want obj.s == ":Hello::12345:"
}
Lo voglio in modo che ogni elemento inserito sia circondato da::
Quindi, nell'esempio dato, s = ": Hello :: 12345 " dovrebbe essere il risultato finale. Qual è la mia domanda, come posso dire all'oggetto che quando mai un <<something
, metti:: intorno a qualcosa.
È possibile?
Soluzione
prova questo:
class MyObject {
public:
template <class T>
MyObject &operator<<(const T &x) {
s << ':' << x << ':';
return *this;
}
std::string to_string() const { return s.str(); }
private:
std::ostringstream s;
};
MyObject obj;
obj << "Hello" << 12345;
std::cout << obj.to_string() << std::endl;
Ci sono alcune cose che non sarai in grado di spingere nello stream, ma dovrebbe funzionare per tutte le basi.
Altri suggerimenti
Puoi trovare le risposte per Come posso creare il mio ostream / streambuf ? utile.
Avrei un approccio leggermente diverso e avrei creato un oggetto formatter.
#include <iostream>
template<typename T>
class Format
{
public:
Format(T const& d):m_data(d) {}
private:
template<typename Y>
friend std::ostream& operator<<(std::ostream& str,Format<Y> const& data);
T const& m_data;
};
template<typename T>
Format<T> make_Format(T const& data) {return Format<T>(data);}
template<typename T>
std::ostream& operator<<(std::ostream& str,Format<T> const& data)
{
str << ":" << data.m_data << ":";
}
int main()
{
std::cout << make_Format("Hello") << make_Format(123);
}