I was trying to write a method that would take parameters using the >> operator as parameters similar to std::cin but I don't know how. Is it possible to create this kind of method that would take this stream like parameter, convert it properly (for example convert all ints to strings etc) and then save to an std::string variable?
Here is an example of how I would like to run the function:
int i = 0;
myMethod << "some text" << i << "moar text";
Inside that method I would like to take those parameters and store in a string.
Edit
I will try to explain exactly what this application is about: I Am trying to make a Clogger singleton class which will be used to save logs to a file. With this construction, I can call *CLogger::instance() << "log stuff"; from anywhere in the code and that's OK. Thanks to answers from this topic I have come to this. The problem is that each operator<< I use, then the object is going to be called. So if I do *CLogger::instance() << "log stuff " << " more stuff " << " even more";` this method(?) is going to be called 3 times:
template<typename T>
CLogger& operator<<(const T& t)
{
...
return *this;
}
That's not good for me as I intend to add some text before and after each log line. For example I would always like to add time before and std::endl after. Following the example I gave instead of getting:
[00:00] log stuff more stuff even more
I would get:
[00:00] log stuff
[00:00] more stuff
[00:00] even more
So I made an attempt to remove this behaviour by changing the method like this:
template<typename T>
CLogger& operator<<(const T& t)
{
ostringstream stream;
stream << t;
m_catString += stream.str();
if (stream.str() == "\n")
{
push_back(m_catString);
m_catString.clear();
}
return *this;
}
This way the program knows when to push new log line if I add "\n" at the end. Its nearly ok, as I bet I will forget to add this. Is there any more clever way?
You can't pass parameters to a method using <<, you need an object.
Something like this:
struct A
{
template<typename T>
A& operator<<(const T& t)
{
std::ostringstream stream;
stream << t;
data += stream.str();
return *this;
}
std::string data;
};
// ...
A a;
a << "Hello " << 34 << " World";
std::cout << a.data;
Regarding your update:
The most obvious thing is to implement the operator in CLogger instead and get rid of the Pusher class; that would let you write *CLogger::instance() << "sample text" << 10;
If you can't do that for some reason (you're giving out information piecemeal, so it's hard to tell), you can declare Pusher a friend and use the same method as everywhere else:
struct Pusher
{
template<typename T>
Pusher& operator<<(const T& t)
{
std::ostringstream stream;
stream << t;
CLogger::instance()->push_back(stream.str());
return *this;
}
};
The only way I know is creating a class class Method and then overload the operator<<, operators overloading
template<class T>
Method &operator<<(const T &x)
{
// Do whatever you like
return *this;
}
Then you can use it like :
Method myMethod;
myMethod << ... ;
you can look at this question about creating a cout-like class
std::cin and std::cout are not functions by the way
EDIT
class CLogger
{
...
template<typename T>
CLogger& operator<<(const T& t)
{
push_back(std::to_string(t));
return *this;
}
};
You don't have to create a class Pusher, just overload the operator in your first class, now you can use it with your object :
myCLogger << t; // this would call the function push back
Related
I want to modify cout so that the text is displayed with, say, a 30ms delay between the printing of each character... I can't imagine I am the first person to want to do this using cout, but I also can't find any example of the same.
To be clear, I want to override the stream insertion operator (not overload).
I have already written my own output functions, I want to see if it is possible to modify the standard behavior for an entire solution.
You may do something like:
class MyDelayStream
{
public:
MyDelayStream(std::ostream& os) : os(os) {}
template <typename T>
MyDelayStream& operator <<(const T& t)
{
using namespace std::literals;
std::stringstream ss;
ss << t;
for (auto c : ss.str()) {
std::this_thread::sleep_for(30ms);
os << c;
}
return *this;
}
private:
std::ostream& os;
};
And then use it like:
MyDelayStream s(std::cout);
s << "hello" << 42 << '\n';
The hard (missing) part is manipulator and function as std::endl.
I have a C++ class where I place many std::cout statements to print informative text messages about a mass of signals that this class is handling. My intentition is to redirect these text messages to a function named log. In this function, I have flag named mVerbose which defines if the log text should be printed. The content of this function is as follows:
void XXXProxy::log(std::stringstream& ss)
{
if(mVerbose)
{
std::cout << ss;
ss << "";
}
}
Then, the caller code snippet to this function is as follows:
std::stringstream logStr;
logStr << "SE"
<< getAddr().toString()
<< ": WAITING on epoll..."
<< std::endl;
log(logStr);
I would like to overload the << operator in my XXXProxy in a way that I can get rid of creating a std::stringstream object and calling the log function. I want to be able to log the text messages as below and let the << operator aggregate everything into:
<< "SE"
<< getAddr().toString()
<< ": WAITING on epoll..."
<< std::endl;
So I wouldlike to have an member << function that looks like:
void XXXProxy::operator << (std::stringstream& ss)
{
if(mVerbose)
{
std::cout << ss;
ss << "";
}
}
QUESTION
I am relatively a novice C++ developer and get lots of compilation errors when attemting to write the above stated like << operator. Could you please make some suggestions or direct me to some links for me to correctly implement this << operator. Thanks.
If you don't want to use std::cout directly and you want to have your own Log class, you could implement a simple wrapper providing the same interface of std::ostream: operator<<:
class Log {
private:
std::ostream& _out_stream;
//Constructor: User provides custom output stream, or uses default (std::cout).
public: Log(std::ostream& stream = std::cout): _out_stream(stream) {}
//Implicit conversion to std::ostream
operator std::ostream() {
return _out_stream;
}
//Templated operator>> that uses the std::ostream: Everything that has defined
//an operator<< for the std::ostream (Everithing "printable" with std::cout
//and its colleages) can use this function.
template<typename T>
Log& operator<< (const T& data)
{
_out_stream << data;
}
}
So if you implement std::ostream& operator>>(std::ostream& os , const YourClass& object) for your classes, you can use this Log class.
The advantage of this approach is that you use the same mechanism to make std::cout << your_class_object work, and to make the class work with the Log.
Example:
struct Foo
{
int x = 0; //You marked your question as C++11, so in class initializers
//are allowed.
//std::ostream::operator<< overload for Foo:
friend std::ostream& operator<<(std::ostream& os , const Foo& foo)
{
os << foo.x;
}
};
int main()
{
Log my_log;
Foo my_foo;
my_foo.x = 31415;
my_log << my_foo << std::endl; //This prints "31415" using std::cout.
}
Possible improvements:
You could write a extern const of class Log, and make the class implement a singleton. This allows you to access the Log everywhere in your program.
It's common in log outputs to have a header, like Log output (17:57): log message. To do that, you could use std::endl as a sentinel and store a flag that says when the next output is the beginning of a line (the beginning of a log message). Checkout the next answer for a complete and working implementation.
References:
std::ostream
operator<< for std::ostream
std::enable_if
std::is_same
decltype specifier
The timestamp of the example was only that, an example :).
But if you like that, we could try to implement it. Thankfully to C++11 and its STL's big improvements, we have an excellent time/date API: std::chrono
std::chronois based in three aspects:
Clocks
Durations
Time points
Also, chrono provides three types of clocks, std::system_clock, std::steady_clock , and std::high_resolution_clock. In our case, we use std::system_clock (We want access to the date-time, not meassuring precise time intervals).
For more info about std::chrono, checkout this awsome Bo Qian's youtube tutorial.
So if we have to implement a time stamp for our log header, we could do this:
EDIT: Like other good things, C++ templates are good tools until you overuse it.
Our problem was that std::endl is a templated function, so we cannot pass it directly to
annother templated function as parammeter (operator<< in our case), because the compiler cannot deduce std::endl template argumments directly. Thats the recurrent error "unresolved overloaded function type".
But there is a much simpler way to do this: Using an explicit overload of operator<< for std::endl only, and other templated for everything else:
class Log
{
private:
std::ostream& _out_stream;
bool _next_is_begin;
const std::string _log_header;
using endl_type = decltype( std::endl ); //This is the key: std::endl is a template function, and this is the signature of that function (For std::ostream).
public:
static const std::string default_log_header;
//Constructor: User passes a custom log header and output stream, or uses defaults.
Log(const std::string& log_header = default_log_header , std::ostream& out_stream = std::cout) : _log_header( log_header ) , _out_stream( out_stream ) , _next_is_begin( true ) {}
//Overload for std::endl only:
Log& operator<<(endl_type endl)
{
_next_is_begin = true;
_out_stream << endl;
return *this;
}
//Overload for anything else:
template<typename T>
Log& operator<< (const T& data)
{
auto now = std::chrono::system_clock::now();
auto now_time_t = std::chrono::system_clock::to_time_t( now ); //Uhhg, C APIs...
auto now_tm = std::localtime( &now_time_t ); //More uhhg, C style...
if( _next_is_begin )
_out_stream << _log_header << "(" << now_tm->tm_hour << ":" << now_tm->tm_min << ":" << now_tm->tm_sec << "): " << data;
else
_out_stream << data;
_next_is_begin = false;
return *this;
}
};
const std::string Log::default_log_header = "Log entry";
This code snippet works perfectly. I have pushed the complete implementation to my github account.
Reference:
std::chrono
std::chrono::system_clock
std::chrono::system_clock::now()
std::time_t
std::chrono::system_clock::to_time_t()
std::tm
std::localtime()
Is it possible to write a method that takes a stringstream and have it look something like this,
void method(string str)
void printStringStream( StringStream& ss)
{
method(ss.str());
}
And can be called like this
stringstream var;
printStringStream( var << "Text" << intVar << "More text"<<floatvar);
I looked up the << operator and it looks like it returns a ostream& object but I'm probably reading this wrong or just not implementing it right.
Really all I want is a clean way to concatenate stuff together as a string and pass it to a function. The cleanest thing I could find was a stringstream object but that still leaves much to be desired.
Notes:
I can't use much of c++11 answers because I'm running on Visual Studio 2010 (against my will, but still)
I have access to Boost so go nuts with that.
I wouldn't be against a custom method as long as it cleans up this mess.
Edit:
With #Mooing Duck's answer mixed with #PiotrNycz syntax I achieved my goal of written code like this,
try{
//code
}catch(exception e)
{
printStringStream( stringstream() << "An exception has occurred.\n"
<<" Error: " << e.message
<<"\n If this persists please contact "<< contactInfo
<<"\n Sorry for the inconvenience");
}
This is as clean and readable as I could have hoped for.
Hopefully this helps others clean up writing messages.
Ah, took me a minute. Since operator<< is a free function overloaded for all ostream types, it doesn't return a std::stringstream, it returns a std::ostream like you say.
void printStringStream(std::ostream& ss)
Now clearly, general ostreams don't have a .str() member, but they do have a magic way to copy one entire stream to another:
std::cout << ss.rdbuf();
Here's a link to the full code showing that it compiles and runs fine http://ideone.com/DgL5V
EDIT
If you really need a string in the function, I can think of a few solutions:
First, do the streaming seperately:
stringstream var;
var << "Text" << intVar << "More text"<<floatvar;
printStringStream(var);
Second: copy the stream to a string (possible performance issue)
void printStringStream( ostream& t)
{
std::stringstream ss;
ss << t.rdbuf();
method(ss.str());
}
Third: make the other function take a stream too
Make your wrapper over std::stringstream. In this new class you can define whatever operator << you need:
class SSB {
public:
operator std::stringstream& () { return ss; }
template <class T>
SSB& operator << (const T& v) { ss << v; return *this; }
template <class T>
SSB& operator << (const T* v) { ss << v; return *this; }
SSB& operator << (std::ostream& (*v)(std::ostream&)) { ss << v; return *this; }
// Be aware - I am not sure I cover all <<'s
private:
std::stringstream ss;
};
void print(std::stringstream& ss)
{
std::cout << ss.str() << std::endl;
}
int main() {
SSB ssb;
print (ssb << "Hello" << " world in " << 2012 << std::endl);
print (SSB() << "Hello" << " world in " << 2012 << std::endl);
}
For ease of writing objects that can be inserted into a stream, all these classes overload operator<< on ostream&. (Operator overloading can be used by subclasses, if no closer match exists.) These operator<< overloads all return ostream&.
What you can do is make the function take an ostream& and dynamic_cast<> it to stringstream&. If the wrong type is passed in, bad_cast is thrown.
void printStringStream(ostream& os) {
stringstream &ss = dynamic_cast<stringstream&>(os);
cout << ss.str();
}
Note: static_cast<> can be used, it will be faster, but not so bug proof in the case you passed something that is not a stringstream.
Since you know you've got a stringstream, just cast the return value:
stringstream var;
printStringStream(static_cast<stringstream&>(var << whatever));
Just to add to the mix: Personally, I would create a stream which calls whatever function I need to call upon destruction:
#include <sstream>
#include <iostream>
void someFunction(std::string const& value)
{
std::cout << "someFunction(" << value << ")\n";
}
void method(std::string const& value)
{
std::cout << "method(" << value << ")\n";
}
class FunctionStream
: private virtual std::stringbuf
, public std::ostream
{
public:
FunctionStream()
: std::ostream(this)
, d_function(&method)
{
}
FunctionStream(void (*function)(std::string const&))
: std::ostream(this)
, d_function(function)
{
}
~FunctionStream()
{
this->d_function(this->str());
}
private:
void (*d_function)(std::string const&);
};
int main(int ac, char* av[])
{
FunctionStream() << "Hello, world: " << ac;
FunctionStream(&someFunction) << "Goodbye, world: " << ac;
}
It is worth noting that the first object sent to the temporary has to be of a specific set of types, namely one of those, the class std::ostream knows about: Normally, the shift operator takes an std::ostream& as first argument but a temporary cannot be bound to this type. However, there are a number of member operators which, being a member, don't need to bind to a reference! If you want to use a user defined type first, you need to extract a reference temporary which can be done by using one of the member input operators.
I have a custom logging class that supports iostream-syntax via a templated operator <<:
template< class T >
MyLoggingClass & operator <<(MyLoggingClass &, const T &) {
// do stuff
}
I also have a specialized version of this operator that is supposed to be called when a log-message is complete:
template< >
MyLoggingClass & operator <<(MyLoggingClass &, consts EndOfMessageType &){
// build the message and process it
}
EndOfMessageType is defined like this:
class EndOfMessageType {};
const EndOfMessageType eom = EndOfMessageType( );
The global constant eom is defined so that users can use it just like std::endl at the end of their log-messages. My question is, are there any pitfalls to this solution, or is there some established pattern to do this?
Thanks in advance!
std::endl is a function, not an object, and operator<< is overloaded for accepting a pointer to a function taking and returning a reference to ostream. This overload just calls the function and passes *this.
#include <iostream>
int main()
{
std::cout << "Let's end this line now";
std::endl(std::cout); //this is the result of cout << endl, or cout << &endl ;)
}
Just an alternative to consider.
By the way, I don't think there is any need to specialize the operator: a normal overload does just as well, if not better.
I think your solution is acceptable. If you wanted to do it differently, you could create a class Message, that would be used instead of the your MyLoggingClass and provided automatic termination.
{
Message m;
m << "Line: " << l; // or m << line(l)
m << "Message: foo"; // or m << message("foo");
log << m; // this would automatically format the message
}
I have done it this way, like some other people did. Have a function Error / Log / Warning / etc that could look like this
DiagnosticBuilder Error( ErrType type, string msg, int line );
This will return a temporary builder object, whose class is basically defined like
struct DiagnosticBuilder {
DiagnosticBuilder(std::string const& format)
:m_emit(true), m_format(format)
{ }
DiagnosticBuilder(DiagnosticBuilder const& other)
:m_emit(other.m_emit), m_format(other.m_format), m_args(other.m_args) {
other.m_emit = false;
}
~DiagnosticBuilder() {
if(m_emit) {
/* iterate over m_format, and print the next arg
everytime you hit '%' */
}
}
DiagnosticBuilder &operator<<(string const& s) {
m_args.push_back(s);
return *this;
}
DiagnosticBuilder &operator<<(int n) {
std::ostringstream oss; oss << n;
m_args.push_back(oss.str());
return *this;
}
// ...
private:
mutable bool m_emit;
std::string m_format;
std::vector<std::string> m_args;
};
So if you are building a log message in a loop, be it so
DiagnosticBuilder b(Error("The data is: %"));
/* do some loop */
b << result;
As soon as the builder's destructor is called automatically, the message is emitted. Mostly you would use it anonymously
Error("Hello %, my name is %") << "dear" << "litb";
I'm writting a log class in c++. This class is an singleton. I want to add logs in such a way:
Log::GetInstance() << "Error: " << err_code << ", in class foo";
Ok, and inside a Log object, I want to save this whole line at the time when the last argument comes (", in class foo" in this example).
How to detect the last one << argument? << a << b << is_this_last << maybe_this_is << or_not.
I dont to use any end tags.
You can solve this problem by not using a singleton. If you make a function like this:
Log log()
{
return Log();
}
You can add a log almost the same way you did before:
log() << "Error: " << err_code << ", in class foo";
The difference is that the destructor of the Log object gets called after this line. So now you have a way to detect when the last argument has been processed.
I would have your Log::GetInstance return a proxy object instead of the log object itself. The proxy object will save the data that's written to it, and then in its destructor, it'll actually write the accumulated data to the log.
You make Log return a different object after the operator << .
template<typename T>
LogFindT operator<<(Log aLog, T const& data)
{
// Put stuff in log.
log.putStuffInLog(data);
// now return the object to detect the end of the statement.
return LogFindT(aLog);
}
struct LogFindT
{
LogFindT(Log& aLog) : TheLog(aLog) {}
Log& TheLog;
~LogFindT()
{
// Do stuff when this object is eventually destroyed
// at the end of the expression.
}
};
template<typename T>
LogFindT& operator<<(LogFindT& aLog, T const& data)
{
aLog.TheLog.putStuffInLog(data);
// Return a reference to the input so we can chain.
// The object is thus not destroyed until the end of the stream.
return aLog;
}
I think Jerry and Martin have given the best suggestion, but for the sake of completeness, the first thing I thought of was std::endl.
If you implemented Log within the iostream system by a custom streambuf class, then you can simply add << endl or << flush at the end of the line. Since you're asking, I suppose you didn't.
But you can mimic the way endl works. Either add a manipulator handler
Log &operator<< ( Log &l, Log & (*manip)( Log & ) )
{ return manip( l ); } // generically call any manipulator
Log &flog( Log &l ) // define a manipulator "flush log"
{ l->flush(); return l; }
or add a dedicated operator<<
struct Flog {} flog;
Log &operator<< ( Log &l, Flog )
{ l->flush(); return l; }
Don't get too clever with your operators. You should overload operators when it makes sense to do so. Here you don't should not.
That just looks weird.
You should just have a static method that looks like this:
Log::Message( message_here );
which takes a std::string. Then clients have the head-ache of figuring out how to assemble the error string.
Here is a solution based on #martin-york's answer. Slightly modified to use member operator in the structs.
#include<sstream>
#include<iostream>
struct log_t{
void publish(const std::string &s){
std::cout << s << std::endl;
}
};
struct record_t{
struct record_appender_t
{
record_appender_t(record_t& record_) : record(record_) {}
record_t& record;
~record_appender_t()
{
// Do stuff when this object is eventually destroyed
// at the end of the expression.
record.flush();
}
template<typename T>
record_appender_t& operator<<(T const& data)
{
record.stream() << data;
// Return a reference to the input so we can chain.
// The object is thus not destroyed until the end of the stream.
return *this;
}
};
std::ostringstream message;
log_t log;
void flush(){
log.publish(message.str());
}
std::ostringstream& stream() {
return message;
}
template<typename T>
record_appender_t operator<<(T const& data)
{
// Put stuff in log.
message << data;
// now return the object to detect the end of the statement.
return record_appender_t(*this);
}
};
#define LOG \
record_t()
int main(){
LOG << 1 << 2 << "a";
}
There's no good way to do what you want. C and C++ are simply not line-oriented languages. There is no larger unit like a "line of code" or anything, nor are chained calls combined in any way.
In C++ the expression "a << b << c << d" is exactly equivalent to three separate calls to operator<<, like this:
t1 = a;
t2 = t1.operator<<(b);
t3 = t2.operator<<(c);
t4 = t3.operator<<(d);
That's why C++ ostreams use endl as an explicit end-of-line marker; there's just no decent way to do it otherwise.