I have this sample block of code:
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main(){
string blank = " ";
cout << "Hello" << blank << "47";
}
I have a lot of cout's of this type in my original code.
I want to be able to change the blank string to setw(2) function without having to replace blank with setw(2) on each and every cout I have in my code.
So is there a way to set a cpp function to a variable?
So I can call the function by typing the name?
for example:
func blank = setw(2);
cout<< "Hello" << blank << "47";
The type of std::setw(x) is unspecified, but you don't need to know it.
You can just use auto:
auto blank = std::setw(2);
As #StoryTeller noted, while this should work on sane implementations, it's not guaranteed to.
A safer option would be to make a class with overloaded <<:
struct blank_t {} blank;
std::ostream &operator<<(std::ostream &s, blank_t)
{
return s << std::setw(2);
}
std::setw is a manipulator. Its type is unspecified and implementation specific.
So is there a way to set a cpp function to a variable?
With C++11 you can use function objects, notably std::function. And you also have lambda expressions.
I am not sure you want to use it in your case.
So learn to use your source code editor. Replace every occurrence of blank with the appropriate stuff, that is std::setw(2) .... That makes your code more readable. Good editors are able to do that easily.
You could abuse the preprocessor, and have
#define blank setw(2)
but in your case that is a bad idea (because the code remains unreadable). Even using auto as answered by HolyBlackCat keeps your code unreadable and confusing.
Code is much more often read than written. Keep it readable (even by yourself, in a few weeks).
If you have a huge (million-line) project, spend perhaps a few minutes to write some script to change your source code in such case. BTW, with GNU emacs it is easy (since emacs is a scriptable editor).
An alternative solution is to write a small wrapper class whose only purpose is to provide an overloaded operator<< for an encapsulated referenced object. You can templatise that class so it works with everything that you could feed to an std::ostream in the first place.
Here is an example:
#include <iostream>
#include <iomanip>
#include <string>
template <class T>
struct Blank {
Blank(T const& t) : t(t) {}
T const& t;
};
// utility function so that you can use type deduction at the call site:
template <class T>
Blank<T> blank(T const& t) {
return Blank<T>(t);
}
template <class T>
std::ostream& operator<<(std::ostream& os, Blank<T> const& blank) {
os << std::setw(2) << blank.t;
return os;
}
int main() {
std::cout << "Hello" << blank("4") << blank(7) << blank(std::string("8")) << '\n';
}
It's not exactly the syntax you've asked for, but it comes pretty close.
You also have to make sure that no encapsulated object is destroyed before it's used in operator<< (because then you'd have undefined behaviour due to a dangling reference), but that's easy to accomplish if never create named Blank objects.
Related
How typedef is used to define variables like int as integer or char as character. Is there any way I can do the same so i can use Print instead of cout in c++?
std::cout is an object.
You can give it another name using a reference:
std::cout << "Hello ";
std::ostream& Print = std::cout;
Print << "world\n";
But, um, please don't. It is well understood by most what std::cout is and does; hiding it behind another name just introduces confusion for confusion's sake.
No.
Generally, you have
using (or typedef) for type aliases
references for variable aliases
inline functions (or macros) for function aliases
So an inline function might be a good alternative in your case (Print sounds like a function):
template<typename T>
inline void Print(T const& stuff)
{
std::cout << stuff;
}
int main()
{
Print("Hello");
Print(42);
Print("world");
}
Now you can e.g. easily change everything that used Print to print to std::cerr instead of std::cout by changing a single line in your code.
This works:
stringstream temp;
temp << i;
result_stream << transform(temp.str());
(transform is a function that takes a string and returns a string; i is an int). However, my attempt to let C++11 create a temporary object without a name didn't work:
result_stream << transform((stringstream() << i).str());
I thought it would work, since the second << should just return the first argument and I'd be able to use str() on that. But I get this error:
error: 'class std::basic_ostream<char>' has no member named 'str'
I'm using g++ 4.8.1 (MinGW-W64).
Is there a way to accomplish this (i.e. write code like this using an unnamed temporary)? (The above code is a bit simplified, and the actual code involves using << on arguments other than int.)
This doesn't work because the second << is std::ostream &operator<<(std::ostream &, int); and so the return type is ostream& which has no member str().
You would have to write:
result_stream << transform( static_cast<stringstream &>(stringstream() << i).str() );
Update (2019): According to LWG 1203 the standard may be changed in future (and one major implementation already has) so that this code no longer works, and a simpler code works instead. See this question for detail.
In the interim period, apparently the following works on both old and new:
result_stream << transform( static_cast<stringstream &>(stringstream().flush() << i).str() );
// ^^^^^^^^
This should not be a performance penalty since flushing an empty stream has no effect...
operator<<() returns a reference to the base class std::ostream contained within the std::stringstream. The base class doesn't contain the str() method. You can cast it back down to a std::stringstream&:
result_stream << transform(static_cast<std::stringstream&>(std::stringstream() << i).str());
The result of the << operator on the temporary stringstream is an ostream. There is no str() method on an ostream.
Use to_string instead:
using std::to_string;
result_stream << transform(to_string(i));
You can define a helper to_string to handle objects not covered by std::to_string.
template <typename T>
std::string to_string (const T &t) {
std::ostringstream oss;
oss << t;
return oss.str();
}
For example, if you had a class Foo that understood redirection to an ostream, and f was an instance of Foo, then you could do:
result_stream << transform(to_string(f));
Try it online!
If you actually want to use a lot of redirection to build up a string before transforming, you could create a helper object for that as well.
struct to_string_stream {
std::ostringstream oss;
template <typename T>
auto & operator << (const T &t) { oss << t; return *this; }
operator std::string () const { return oss.str(); }
void clear () { oss.string(std::string()); }
};
Then, you could do something like:
to_string_stream tss;
result_stream << transform(tss << i << ':' << f);
Try it online!
Tried and failed to do this for C++11 (in 2009):
http://cplusplus.github.io/LWG/lwg-active.html#1203
libc++ went outlaw and implemented it anyway.
It is up for reconsideration, but can not possibly be standardized prior to 2017 (standardization is a glacial process).
I recently started to use Boost C++ library and I am testing the any class which can hold any data type. Actually I am trying to define the operator<< to print easily the content of any variable of type any (and sure, the class of the content should have the operator<< defined too).
I only started by sample types ( int, double ...) because they have be displayed by default. And till now, I have this code :
#include <boost/any.hpp>
#include <iostream>
#include <string>
using namespace std;
using namespace boost;
ostream& operator<<(ostream& out, any& a){
if(a.type() == typeid(int))
out << any_cast<int>(a);
else if(a.type() == typeid(double))
out << any_cast<double>(a);
// else ...
// But what about other types/classes ?!
}
int main(){
any a = 5;
cout << a << endl;
}
So the problem here is that I have to enumerate all possible types. Is there any way to cast the variable to a particular type having the type_info of this particular type ?
Boost.Any any
With boost::any you cannot do that as others have already noted in comments. That is because boost::any forgets everything about the type of value it stores and requires you to know what type is there. While you have no way to enumerate every possible type.
The solution is to change boost::any so that it forgets everything about the type of value it stores except for how to stream it out. Mooing Duck provided one solution in comments. Another would be to write a new version of boost::any but extend its internals to support the streaming operation.
Boost.Spirit hold_any
Boost.Spirit already provides something like that in <boost/spirit/home/support/detail/hold_any.hpp>.
Boost.TypeErasure any
A far better approach is however to use Boost.TypeErasure's any as was mentioned by Kerrek SB in his comment.
An example for your case (use of <<) would look like this:
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/operators.hpp>
#include <iostream>
#include <string>
int main() {
typedef
boost::type_erasure::any<
boost::mpl::vector<
boost::type_erasure::destructible<>,
boost::type_erasure::ostreamable<>,
boost::type_erasure::relaxed
>
> my_any_type;
my_any_type my_any;
my_any = 5;
std::cout << my_any << std::endl;
my_any = 5.4;
std::cout << my_any << std::endl;
my_any = std::string("text");
std::cout << my_any << std::endl;
}
Right, I'm not even sure how to correctly formulate this; I feel it's a bit of an involved question. I'm sure someone can help me out here though.
This is what I want to do:
Have a single class that I can send stuff to, like this.
icl << "Blah blah blah" << std::endl;
I want to be able to .attach() classes that inherit std::basic_ostream to it.
Those classes would then be able to format the output their own way. One might add a timestamp and write to a log, the other might write it to the console, the other might display it in-game.
Anyone care to get me started in the right direction? Here's the idea I pretty much have.
#include <vector>
class OutputMan {
std::vector<std::basic_ostream&> m_Streams;
public:
void attach(std::basic_ostream& os) {
m_Streams.push_back(os);
}
}
Question #1: What do I need to inherit and override to send
icl << "Blah!" << std::endl;
To every stream in m_Streams?
Question #2: How do I inherit std::basic_ostream and create a class that changes the output to, for example, add a timestamp to the start of it? I also want for this class to output to a file.
I think I'd do things a bit differently. I've probably made this just a bit more elaborate than necessary -- I'm afraid I may have gotten a little carried away with trying to put new C++11 features to good use. Anyway, on with the code:
#include <streambuf>
#include <fstream>
#include <vector>
#include <iostream>
#include <initializer_list>
namespace multi {
class buf: public std::streambuf {
std::vector<std::streambuf *> buffers;
public:
typedef std::char_traits<char> traits_type;
typedef traits_type::int_type int_type;
buf(std::vector<std::ofstream> &buf) {
for (std::ofstream &os : buf)
buffers.push_back(os.rdbuf());
}
void attach(std::streambuf *b) { buffers.push_back(b); }
int_type overflow(int_type c) {
bool eof = false;
for (std::streambuf *buf : buffers)
eof |= (buf -> sputc(c) == traits_type::eof());
return eof ? traits_type::eof() : c;
}
};
class stream : public std::ostream {
std::vector<std::ofstream> streams;
buf outputs;
public:
stream(std::initializer_list<std::string> names)
: streams(names.begin(), names.end()),
outputs(streams),
std::ostream(&outputs)
{ }
void attach(std::ostream &b) {
outputs.attach(b.rdbuf());
}
};
}
int main() {
multi::stream icl({"c:\\out1.txt", "c:\\out2.txt"});
icl.attach(std::cout);
icl << "Blah blah blah" << std::endl;
}
As you can see, this already accepts manipulators (which should work with any manipulator, not just std::endl). If you want to write to multiple files (things that could/can be opened as fstreams) you can specify as many of those names in the constructor as you like (within the limits imposed by your system, of course). For things like std::cout and std::cerr for which you don't necessarily have a file name, you can use attach as you originally intended.
I suppose I should add that I'm not entirely happy with this as-is. It'd take some fairly serious rewriting to do it, but after some thought, I think the "right" way would probably be for multi::stream's ctor to be a variadic template instead, so you'd be able to do something like: multi::stream icl("c:\\out1.txt", std::cout);, and it would sort out how to use each parameter based on its type. I may update this answer to include that capability some time soon.
As far as the second question goes, I've written another answer that covers the basic idea, but is probably a bit overly elaborate, so the part you care about may kind of get lost in the shuffle, so to speak -- it has quite a bit of logic to deal with line lengths that you don't really care about (but does produce each output line with a specified prefix, like you want).
You may need something like this:
class OutputMan {
std::vector<std::ostream*> m_Streams;
public:
void attach(std::ostream *os) {
m_Streams.push_back(os);
}
template <typename T>
OutputMan &operator<<(const T &t) {
for (int i=0; i<m_Streams.size(); i++)
*m_Streams[i] << t;
return *this;
}
};
int main() {
ofstream file("test.txt");
OutputMan x;
x.attach(&cout);
x.attach(&cerr);
x.attach(&file);
x << "Hello" << 123;
}
For simplicity I used std::ostream*. To accept stuffs by << I overloaded operator<<.
Note: If you want OutputMan accepts std::endl as well as other things, read here.
I would like to be able to do:
foo(stringstream()<<"number = " << 500);
EDIT: single line solution is crucial since this is for logging purposes. These will be all around the code.
inside foo will print the string to screen or something of the sort.
now since stringstream's operator<< returns ostream&, foo's signature must be:
foo(ostream& o);
but how can I convert ostream& to string? (or char*).
Different approaches to achieving this use case are welcome as well.
The obvious solution is to use dynamic_cast in foo. But the given
code still won't work. (Your example will compile, but it won't do what
you think it should.) The expression std::ostringstream() is a
temporary, you can't initialize a non-const reference with a temporary,
and the first argument of std::operator<<( std::ostream&, char const*)
is a non-const reference. (You can call a member function on a
temporary. Like std::ostream::operator<<( void const* ). So the code
will compile, but it won't do what you expect.
You can work around this problem, using something like:
foo( std::ostringstream().flush() << "number = " << 500 );
std::ostream::flush() returns a non-const reference, so there are no
further problems. And on a freshly created stream, it is a no-op.
Still, I think you'll agree that it isn't the most elegant or intuitive
solution.
What I usually do in such cases is create a wrapper class, which
contains it's own std::ostringstream, and provides a templated
member operator<< which forwards to the contained
std::ostringstream. Your function foo would take a const
reference to this—or what I offen do is have the destructor call
foo directly, so that the client code doesn't even have to worry about
it; it does something like:
log() << "number = " << 500;
The function log() returns an instance of the wrapper class (but see
below), and the (final) destructor of this class calls your function
foo.
There is one slight problem with this. The return value may be copied,
and destructed immediately after the copy. Which will wreck havoc with
what I just explained; in fact, since std::ostringstream isn't
copyable, it won't even compile. The solution here is to put all of the
actual logic, including the instance of std::ostringstream and the
destructor logic calling foo in a separate implementation class, have
the public wrapper have a boost::shared_ptr to it, and forward. Or
just reimplement a bit of the shared pointer logic in your class:
class LogWrapper
{
std::ostringstream* collector;
int* useCount;
public:
LogWrapper()
: collector(new std::ostringstream)
, useCount(new int(1))
{
}
~LogWrapper()
{
-- *useCount;
if ( *useCount == 0 ) {
foo( collector->str() );
delete collector;
delete useCount;
}
}
template<typename T>
LogWrapper& operator<<( T const& value )
{
(*collector) << value;
return *this;
}
};
Note that it's easy to extend this to support optional logging; just
provide a constructor for the LogWrapper which sets collector to
NULL, and test for this in the operator<<.
EDITED:
One other thing occurs to me: you'll probably want to check whether the
destructor is being called as a result of an exception, and not call
foo in that case. Logically, I'd hope that the only exception you
might get is std::bad_alloc, but there will always be a user who
writes something like:
log() << a + b;
where the + is a user defined overload which throws.
I would suggest you to use this utility struct:
struct stringbuilder
{
std::stringstream ss;
template<typename T>
stringbuilder & operator << (const T &data)
{
ss << data;
return *this;
}
operator std::string() { return ss.str(); }
};
And use it as:
void f(const std::string & s );
int main()
{
char const *const pc = "hello";
f(stringbuilder() << '{' << pc << '}' );
//this is my most favorite line
std::string s = stringbuilder() << 25 << " is greater than " << 5 ;
}
Demo (with few more example) : http://ideone.com/J995r
More on my blog : Create string on the fly just in one line
You could use a proxy object for this; this is a bit of framework, but if you want to use this notation in a lot of places then it may be worth it:
#include <iostream>
#include <sstream>
static void foo( std::string const &s )
{
std::cout << s << std::endl;
}
struct StreamProxy
{
std::stringstream stream;
operator std::string() { return stream.str(); }
};
template <typename T>
StreamProxy &operator<<( StreamProxy &s, T v )
{
s.stream << v;
return s;
}
static StreamProxy make_stream()
{
return StreamProxy();
}
int main()
{
foo( make_stream() << "number = " << 500 );
}
This program prints
number = 500
The idea is to have a little wrapper class which can be implicitely converted into a std::string. The << operator is simply forwarded to the contained std::stringstream. The make_stream() function is strictly speaking not necessary (you could also say StreamProxy(), but I thought it looks a bit nicer.
A couple of options other than the nice proxy solution just presented by Frerich Raabe:
Define a static string stream variable in the header that defines the logging function and use the comma operator in your invocation of the logging function so that this variable is passed rather than the ostream& returned by the stream insertion operator. You can use a logging macro to hide this ugliness. The problem with this solution is that it is a bit on the ugly side, but this is a commonly used approach to logging.
Don't use C++ I/O. Use a varargs C-style solution instead. Pass a format string as the first argument, with the remaining arguments being targets for that format string. A problem with this solution is that even if your compiler is smart enough to ensure that printf and its cousins are safe, the compiler probably won't know that this new function is a part of the printf family. Nonetheless, this is also a commonly used approach.
If you don't mind using macros functions, you can make the logging function accept const string&, and use the following macro
#define build_string(expr) \
(static_cast<ostringstream*>(&(ostringstream().flush() << expr))->str())
And suppose you foo has signature void foo(const string&), you only need the one-liner
foo(build_string("number = " << 500))
This was inspired by James Kanze's answer about static_cast and stringstream.flush. Without the .flush() the above method fails with unexpected output.
Please note that this method should not leak memory, as temporary values, whether in the pointer form or not, are still allocated on the stack and hence destroyed upon return.
Since you're converting to string anyways, why not
void foo(const std::string& s)
{
std::cout << "foo: " << s << std::endl;
}
...
std::stringstream ss;
ss << "number = " << 500;
foo(ss.str());
This is not possible. As the name ostream implies, it is used for output, for writing to it. You could change the parameter to stringstream&. This class has the method str() which returns a std::string for your use.
EDIT I did not read the issue with operator << returning ostream&. So I guess you cannot simply write your statements within the functions argument list but have to write it before.
You can create a small wrapper around std::ostringstream that will convert back to std::string on use, and have the function take a std::string const &. The first approach to this solution can be found in this answer to a different question.
On top of that, you can add support for manipulators (std::hex) if needed.