I am using a template function and I am passing and I may be sending instances of a variety of classes to a string stream. What can I do to make sure this continues to work?
Let me be more specific where do I define the behavior for this? Is there some member that should be on each class being sent to the string stream, should I in some enhance or extend the existing String stream (I was thinking building a class that inherits from sstream and overloads the << operator to handle all the possible classes)?
I had trouble even finding documentation on this, so even links to more resources would be helpful.
It sounds to me like you want to make stream insertion operators. for a class you want to be able to output to a stream, define the free function:
std::ostream& operator<<(std::ostream& stream, const SomeClassType& x)
{
stream << x.someData();
return stream;
}
So if we have SomeClassType z;, and we do std::cout << z (or any other output stream, like an fstream or stringstream), the compiler will look for and find our function, and call it. That is, std::cout << z becomes operator<<(std::cout, z) and inside there you output what you need.
You just need to overload operator<< for those classes, e.g.
struct Point { int x, y; };
std::ostream& operator<<(std::ostream& os, const Point& p)
{
return os << '(' << p.x << ", " << p.y << ')';
}
then you can use it in your function, which might be something like this:
template <class T>
std::string to_string(const T& x)
{
std::stringstream ss;
ss << x;
return ss.str();
}
int main()
{
Point p = {1, 2};
std::string ps = to_string(p);
std::cout << ps << std::endl; // (1, 2)
}
Related
My question is: how to define a factory function that takes a parameter and returns a function pointer pointing to a function that is created according to that parameter? (or any other nice way to achieve the same result)
Explanation
In essence, I want to define a factory function set, which takes a std::string parameter str, and returns a pointer to function pf. The function pointer pf points to a function, just created in set, that takes std::ostream & and returns std::ostream &.
In this way, I want to call with std::cout << set(str) << "text" << std::endl;. I hope that the result of set(str) lives at least as long as this statement.
For your reference, it is from cplusplus that
ostream & operator<< (ostream & (*pf)(ostream &));
More Explanation
This is for a real example, shown as below.
First I have manipulators
std::ostream & black(std::ostream & os)
{
return os << "\033[30m"; // make terminal text black
}
std::ostream & red(std::ostream & os)
{
return os << "\033[31m"; // make terminal text red
}
std::ostream & green(std::ostream & os)
{
return os << "\033[32m"; // make terminal text green
}
so that when I call
std::cout << red << "this text is in red" << std::endl;
I will have the desired effect. So far so good.
Now with a map
std::map<std::string, std::string> code =
{
{"black", "30"},
{"red", "31"},
{"green", "32"}
// ...
// could extend much longer as there are many colors
};
I hope to achieve a similar, customized effect with foo("red") with
void foo(std::string str)
{
std::cout << set(str) << ("this text is in " + str) << std::endl;
}
where set takes "red" and looks up the map code for the corresponding code "31".
But I have problems in implementing the set function. I would appreciate it much if anyone could help me with this!
Two notes:
If possible, I want good performance for the set function, as it will be called again and again.
Forgive me please if I think the wrong way --- So long as you can implement the functionality for set, I don't mind you do it in a different way.
Thank you for reading this long post. Thank you very much!
You are thinking the wrong way about it. What you need to do instead is to create you own parameterized manipulator. Such manipulator can be implemented as a separate class for which you have to overload operator<< :
struct set_color
{
std::string name;
explicit set_color(std::string name)
: name(std::move(name)) { }
friend std::ostream & operator<<(std::ostream & os, const set_color &color)
{
if (color.name == "black")
os << "\033[30m";
else if ... // and so on
...
}
}
You can use a map instead to convert name to color code, but the basic idea is that there is no need to create a bunch of functions for this.
Why make things complicated?
std::string_view color_from_name(std::string_view colorName)
{
static const std::map<std::string_view, std::string_view> colors {
{"red"sv, "\033[31m"sv},
{"green"sv, "\033[32m"sv},
{"black"sv, "\033[30m"sv},
};
return colors.at(colorName);
}
int main() {
std::cout << color_from_name("red") << "tada" << color_from_name("green") << "got it\n";
return 0;
}
https://wandbox.org/permlink/nh2qMKoovh2qVlk2
I think you could globally define another overload of operator<< as such:
using Manipulator = std::function<std::ostream&(std::ostream&)>;
std::ostream& operator<< (std::ostream& stream, Manipulator&>& func) {
return func(stream);
}
std::map<std::string, Manipulator> manipulators;
for (const auto& val : data) {
manipulators.emplace(std::pair<std::string, Manipulator>(val.first,
[&](std::ostream& out) -> std::ostream& { return out << "\033[" << val.second << "m"; }
));
}
If you stored a map of strings to lambda functions as your manipulators, you should be able to make your set() function a simple wrapper returning your lambda.
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'd like to implement a custom manipulator for ostream to do some manipulation on the next item being inserted into the stream. For example, let's say I have a custom manipulator quote:
std::ostringstream os;
std::string name("Joe");
os << "SELECT * FROM customers WHERE name = " << quote << name;
The manipulator quote will quote name to produce:
SELECT * FROM customers WHERE name = 'Joe'
How do I go about accomplishing that?
Thanks.
It's particularly difficult to add a manipulator to a C++ stream, as one has no control of how the manipulator is used. One can imbue a new locale into a stream, which has a facet installed that controls how numbers are printed - but not how strings are output. And then the problem would still be how to store the quoting state safely into the stream.
Strings are output using an operator defined in the std namespace. If you want to change the way those are printed, yet keeping the look of manipulators, you can create a proxy class:
namespace quoting {
struct quoting_proxy {
explicit quoting_proxy(std::ostream & os):os(os){}
template<typename Rhs>
friend std::ostream & operator<<(quoting_proxy const& q,
Rhs const& rhs) {
return q.os << rhs;
}
friend std::ostream & operator<<(quoting_proxy const& q,
std::string const& rhs) {
return q.os << "'" << rhs << "'";
}
friend std::ostream & operator<<(quoting_proxy const& q,
char const* rhs) {
return q.os << "'" << rhs << "'";
}
private:
std::ostream & os;
};
struct quoting_creator { } quote;
quoting_proxy operator<<(std::ostream & os, quoting_creator) {
return quoting_proxy(os);
}
}
int main() {
std::cout << quoting::quote << "hello" << std::endl;
}
Which would be suitable to be used for ostream. If you want to generalize, you can make it a template too and also accept basic_stream instead of plain string. It has different behaviors to standard manipulators in some cases. Because it works by returning the proxy object, it will not work for cases like
std::cout << quoting::quote;
std::cout << "hello";
Try this:
#include <iostream>
#include <iomanip>
// The Object that we put on the stream.
// Pass in the character we want to 'quote' the next object with.
class Quote
{
public:
Quote(char x)
:m_q(x)
{}
private:
// Classes that actual does the work.
class Quoter
{
public:
Quoter(Quote const& quote,std::ostream& output)
:m_q(quote.m_q)
,m_s(output)
{}
// The << operator for all types. Outputs the next object
// to the stored stream then returns the stream.
template<typename T>
std::ostream& operator<<(T const& quoted)
{
return m_s << m_q << quoted << m_q;
}
private:
char m_q;
std::ostream& m_s;
};
friend Quote::Quoter operator<<(std::ostream& str,Quote const& quote);
private:
char m_q;
};
// When you pass an object of type Quote to an ostream it returns
// an object of Quote::Quoter that has overloaded the << operator for
// all types. This will quote the next object and the return the stream
// to continue processing as normal.
Quote::Quoter operator<<(std::ostream& str,Quote const& quote)
{
return Quote::Quoter(quote,str);
}
int main()
{
std::cout << Quote('"') << "plop" << std::endl;
}
[EDIT: "True manipulator semantics" (i.e. a persistent quoting state) could also be achieved by wrapping an std::ostream rather than deriving from it, as noted by BenĂ´it in the comments.]
To the best of my knowledge this cannot be done directly without either deriving a new class from std::ostream or similar, or wrapping such a class in another class that forwards most methods to its contained std::ostream object. That's because, for the code example you provide to work, you will need to somehow modify the behaviour of std::ostream& operator<<(std::ostream&, std::string const&), which is defined somewhere in the iostreams hierarchy (or possibly wherever std::string is defined). You will also need to use the (somewhat ugly) facilities in ios_base to record a boolean flag holding the current quoting state. Look up ios_base::xalloc(), ios_base::iword() and ios_base::pword() to find out how to do that.
However, if you are willing to use the following syntax:
os << "SELECT * FROM customers WHERE name = " << quote(name);
This can be done very simply using a global function (in an appropriate namespace of course).
This syntax has the advantage that quoting is not persistent, meaning it can't "leak out" when a function sets the quote formatting flag and forgets to set it back to its original value.
Or just use OTL which basically already implements a stream interface for SQL very similarly to your example.