How can I pretty-print a struct with its fields being named? - c++

Suppose I have a
struct foo { int bar; double baz; };
And a struct foo s; somewhere. I would like to be able to write magic(s) and get a string, or text printed to cout, which includes not just the values of s.bar and s.baz, but also the identifiers 'bar' and 'baz'.
I know C++ doesn't have proper reflection, but maybe something RTTIish (I'm not well-versed in RTTI)? Or perhaps with some minor decoration of the class declaration?
Note: Of course I'm asking about a solution which would work for any type, or at least any struct; obviously I can implement an operator<< for foo's.

We may well have to wait until C++ get reflection facilities added to the language.
This is being actively worked on, by WG21 SG7. What's that? WG21 is the working group of the International Standards Organization (ISO) which develops the C++ language standards. SG7 is the sub-group in charge of exploring the possibilities reflection.
SG7 has a Google Group in which it discusses its ongoing work.

You could implement:
inline std::ostream& operator<<(
std::ostream& os, // stream object
const foo& f
)
{
os << /*ToDo - nice formatting of data members*/
return os;
}
Then this will work with cout etc:
foo f; cout << "My foo is " << f << ".";

Related

Is it possible to overload operator<< like this? [duplicate]

This question already has answers here:
How to define a static operator<<?
(4 answers)
Closed 9 years ago.
Let's say I have a class called "Logger". The name is self explanatory, it logs stuff. I have a static method, which logs stuff (Logger::log(string msg)).
I wanted to overload the operator <<, so that I could do something like:
Logger << "AW YEAH, I LOVE C++";
I tried to do this, but couldn't. What I managed, was this:
Logger l;
l << ":(";
...
is it possible what I want to do? And if yes, how?
Thank You in advance :)
If Logger is the name of a class then of course you can't do that. Use something like
Logger &log() {
static Logger l;
return l;
}
log() << "And the answer is" << 42;
Assuming you want to leverage the output operators provide by std::ostream you should not try to overload the output operator! Instead, you'd create a suitable stream buffer (i.e., a class derived from std::streambuf) and implement your custom output logic in that class's overflow() and sync() methods. Your logger would then derive from std::ostream and initialize its base class to use your custom stream buffer.
Overloaded operators operate on values, not on types.
Maybe you should rename your class, and then create a suitable global object. For example:
logger.h:
class mylogger { /* ... */ };
extern mylogger logger;
logger.cpp:
#include "logger.h"
mylogger logger;
Usage:
#include "logger.h"
logger << "Done";
Beware of global initialization issues; though; check out your implementation of std::cout for a way to solve this (e.g. with a Schwartz counter).
It is possible, but you need to figure out what interface you really want. One option is to make your Logger be an std::ostream (inheritance) and then things would kind of work out of the box. The alternative is to maintain a logger that is unrelated (no inheritance) to std::ostream, but then you need to provide Logger& operator<<(Logger&,T const &) for any and all types T you want to log. For the particular case of std::string you could do:
Logger& operator<<(Logger& logger, std::string const& msg) {
logger.log(msg); // need not be, and problably should be static
return logger;
}
Making this generic involves as with most generic code in C++ the use of templates:
template <typename T>
Logger& operator<<(Logger& logger, T const & obj) {
// do specific work based on the type, or a completely generic approach:
std::ostringstream st;
st << obj;
logger.log(st.str());
return logger;
}
At this point you might want to consider adding support for manipulators and... well, if you start down this path, it might make more sense not to create the std::ostringstream in each function, but create a single one as a member, then dump all data into that stream and use some manipulator to extract the string and write it (for example on std::flush or std::ends...)
template <typename T>
Logger& operator<<(Logger& logger, T const& obj) {
logger.stream << obj;
return logger;
}
Logger& operator<<(Logger& logger, std::ostream& (*manip)(std::ostream&)) {
logger.stream << manip;
if (manip == static_cast<std::ostream& (*)(std::ostream&)>(std::flush)) {
logger.write(); // flush to disk
}
return logger;
}
// add support for other manipulators...
Then again you might start wondering if it would not be easier to pull some off the shelf logging library and just use it.

Secure direct access to class members

I wonder if the following syntax can be "admitted" or if good practices consider this as coming from hell. The goal would be to add a level of protection to force the developer to be well-conscious of what he is doing. Here is the syntax :
class MyClass
{
public:
template<bool RemoveProtection = false>
inline std::ofstream& writeStream()
{
static_assert(RemoveProtection, "You're doing it wrong");
return _writeStream;
}
inline const std::ofstream& writeStream() const
{
return _writeStream;
}
protected:
std::ofstream _writeStream;
};
The use would be :
x.writeStream().good(); // <- OK
x.writeStream().put('c'); // <- NOT OK
x.writeStream<true>().put('c'); // <- OK
I find this as a convenient way to tell to the developer : "Beware, you are using a low-level function and you have to be careful with what you are doing". Is it a "acceptable" way of providing a direct access to class members with a kind of "protection" ? Is there other way of coding a such thing ?
Have a look at meagar's comment:
You're making your code ugly, harder to maintain and inconvenient for... what exactly? Define your interface. That is the interface to your class. Do not allow developers to bypass it by using some ridiculous template flag hackery. If you're writing code, you always have to know what you're doing. Having to explicitly type <true> to indicate you especially know what you're doing is just... very, very wrong-headed. Developers have documentation. They don't need training wheels and artificial restrictions, they need clear concise code that lets them get things done. – meagar 2012-10-06 02:41:53Z
A class you provide to others should never be able to get into an unpredicted state when another user uses it. An unpredicted state is in this case a state which you never considered when you were writing the class. As such you should either never allow access to low-level methods of your class or document possible flaws.
Lets say you're writing a logger:
struct MyLogger{
MyLogger(std::string filename) : stream(filename.c_str()){}
template <typename T>
MyLogger& operator<<(const T& v){ stream << v << " "; return *this;}
private:
std::ofstream stream;
};
Ignore that there isn't a copy constructor and that the assignment operand is missing. Also ignore that it's a crude logger, it doesn't even provide a timestamp. However, as you can see, the state of the logger depends completely on the logger's methods, e.g. if the file has been successfully opened it won't be closed until the logger gets destroyed.
Now say that we use your approach:
struct MyLogger{
MyLogger(std::string filename) : stream(filename.c_str()){}
template <typename T>
MyLogger& operator<<(const T& v){ stream << v << " "; return *this;}
template<bool RemoveProtection = false>
inline std::ofstream& writeStream()
{
static_assert(RemoveProtection, "You're doing it wrong");
return stream;
}
inline const std::ofstream& writeStream() const
{
return stream;
}
private:
std::ofstream stream;
};
And now someone uses the following code
logger.writeStream<true>.close();
Bang. Your logger is broken. Of course it's the users fault, since they used <true>, didn't they? But more often than not a user is going to copy example code, especially if he uses a library for the first time. The user sees your example
logger.writeStream().good(); // <- OK
logger.writeStream().put('c'); // <- NOT OK
logger.writeStream<true>().put('c'); // <- OK
and ignores the documentation completely at first. Then he's going to use the first and the last version. Later he discovers that the last version works every time! What a miraculous thing <true> is. And then he starts to blame you for evil things that happen, so you have protect yourself from blatant flames with a documentation which includes a warning:
/**
* \brief Returns a reference to the internal write stream
*
* \note You have to use the template parameter `<true>` in order to use it
*
* \warning Please note that this will return a reference to the internal
* write stream. As such you shouldn't create any state in which
* the logger cannot work, such as closing the stream.
*/
template<bool RemoveProtection = false>
inline std::ofstream& writeStream()
{
static_assert(RemoveProtection, "You're doing it wrong");
return stream;
}
So, what did we get? We still had to put that warning somewhere. It would have been much simpler if we made stream public:
struct MyLogger{
MyLogger(std::string filename) : stream(filename.c_str()){}
template <typename T>
MyLogger& operator<<(const T& v){ stream << v << " "; return *this;}
/**
* The internal write stream. Please look out that you don't create
* any state in which the logger cannot work, such as closing the stream.
*/
std::ofstream stream;
};
or sticked to
/** >put warning here< */
inline std::ofstream & writeStream()
{
return stream;
}
Woops. So either don't allow access to your low-level methods (build a wrapper to specific std::ofstream methods if they should be allowed to use them) or document the possible flaws which can happen if you alter the object's internals to much, but don't go the middle-way and make it look okay with a static_assert.

In c++ is there any Events/delegates/interfaces/notifications! anything?

Say i have these classes
ViewA and ViewB
In objective C using the delegate pattern I could do
#protocol ViewBDelegate{
- (void) doSomething();
}
then in ViewB interface:
id<ViewBDelegate> delegate;
then in ViewA implementation i set the delegate:
viewB.delegate = self;
and now I can call in doSomething from viewB onto any that unknown type delegate.
[delegate doSomething];
"C++ How to Program" has been the worse read an can't find simple examples that demonstrates basic design patterns.
What i'm looking for in C++ is:
events ActionScript and java
or delegates or NSNotifications in Objective C
anything that allows class A, Class B and Class C to know that ClassX
didSomething()!!!
thanks
If I were you, I wouldn't use function pointers to accomplish this task. Leave this option to the gurus ;)
In Boost, there is a beautiful library called signals. It makes your life easier! This is an example of usage:
#include <iostream>
#include <boost/bind.hpp>
#include <boost/signal.hpp>
using namespace std;
using namespace boost;
struct A
{ void A_action() { cout << "A::A_action();" << endl; } };
struct B
{ void B_action() { cout << "B::B_action();" << endl; } };
struct C
{ void C_action() { cout << "C::C_action();" << endl; } };
struct X
{
// Put all the functions you want to notify!
signal<void()> list_of_actions;
void do_something()
{
std::cout << "Hello I am X!" << endl;
list_of_actions(); // send notifications to all functions in the list!
}
};
int main()
{
X x;
A a;
B b;
C c;
x.list_of_actions.connect(bind(&A::A_action, a));
x.list_of_actions.connect(bind(&B::B_action, b));
x.list_of_actions.connect(bind(&C::C_action, c));
x.do_something();
}
This will print:
Hello I am X!
A::A_action();
B::B_action();
C::C_action();
Here is how it works.
First, you declare the place that holds the delegates:
signal<void()> list_of_actions;
Then, you "connect" it to what ever group of functions/functors/callable things you want to call.
x.list_of_actions.connect(bind(&A::A_action, a));
x.list_of_actions.connect(bind(&B::B_action, b));
x.list_of_actions.connect(bind(&C::C_action, c));
Note, that I have used bind. So, that the type of functions in the list_of_actions is the same, but we can connect it to different type of classes. So:
bind(&A::A_action, a)
This thing, produces a callable thing, of type void () as we declared the type of list_of actions earlier. Of course, you specify the instance you want to apply this member function on in the second parameter..
If you are doing multi-threaded stuff, then use its sister signals2.
Hope that helps.
anything that allows class A, Class B
and Class C to know that ClassX
didSomething()!!!
Probably you are looking for signals & slots, which has multiple implementations:
Boost
Qt
I'm sure there are more, but these are the most significant of which I'm aware.
There are no delegates/events/etc.
You can simulate interfaces using pure virtual function, see here for a similar question.
And there are the function pointers...
So basically the answer to you question is no, there are none of that in C++ (don't know about the latest standard), but there are substitutes and workarounds..
Personally I like The Impossibly Fast C++ Delegates by Sergey Ryazanov. Very neat and easy to use implementation, claimed to be faster than Boost::function.
You can find events implemented there, too. I don't use them, however. I implemented my own event handling using .NET style (sender, args).
Neither the C++ language, nor its associated Standard Library, either have delegates or events. There are of course many libraries that implement such things, or you can implement them yourself.
All i know there is a type of method called call-back method(In fact, function pointer).
Delegation? It's just a kind of wrapped call-back method, and, looks advanced
"C++ How to Program" has been the worse read an can't find simple examples that demonstrates basic design patterns
I think that the original Design Patterns book includes examples of how to implement each pattern using C++.

Using a virtually inherited function non-virtually?

I have run into trouble trying to implement functionality for serializing some classes in my game. I store some data in a raw text file and I want to be able to save and load to/from it.
The details of this, however, are irrelevant. The problem is that I am trying to make each object that is interesting for the save file to be able to serialize itself. For this I have defined an interface ISerializable, with purely virtual declarations of operator<< and operator>>.
The class Hierarchy looks something like this
-> GameObject -> Character -> Player ...
ISerializable -> Item -> Container ...
-> Room ...
This means there are many possible situations for serializing the objects of the different classes. Containers, for instance, should call operator<< on all contained items.
Now, since operator>> is virtual, i figured if I wanted to serialize something that implements the functionality defined in ISerializable i could just do something like
ostream & Player::operator<<(ostream & os){
Character::operator<<(os);
os << player_specific_property 1 << " "
<< player_specific_property 2 << "...";
return os;
}
and then
ostream & Character::operator<<(ostream & os){
GameObject::operator<<(os);
os << character_specific_property 1 << " "
<< character_specific_property 2 << "...";
return os;
}
but I quickly learnt that this first attempt was illegal. What I'm asking here is how do I work around this?
I don't feel like implementing a function manually for each class. I guess I'm looking for something like the super functionality from Java.
Any help is appreciated.
-- COMMENTS ON EDIT ------------
Alright, last time I was in a hurry when I was writing the question. The code is now more like it was when I tried to compile it. I fixed the question and the problem I had was unrelated to the question asked. I'm ashamed to say it was caused by an error in the wake of a large refactoring of the code, and the fact that the operator was not implemented in every base class.
Many thanks for the replies however!
The problem is not in your attempt to call a virtual function non-virtually. The problem is this line: os = Character::operator<<(os);. That is an assignment, but std::ostream doesn't have an operator=.
You don't need the assignment anyway. The stream returned is the same stream as the stream you pass in. The only reason it's returned is so you can chain them.
Hence the fix is to just change the code to
ostream & Player::operator<<(ostream & os){
Character::operator<<(os);
os << player_specific_property 1 << " "
<< player_specific_property 2 << "...";
return os;
}
This is not how overloading operator<< for ostream works. The left-hand operator is an ostream (hence you gotta overload it as a free function) and the right-hand operator is your object (which is why the virtual mechanism wouldn't easily work.
I suppose you could try:
class Base
{
//...
virtual std::ostream& output(std::ostream&) const;
};
std::ostream& operator<< (std::ostream& os, const Base& obj)
{
return obj.output(os);
}
Now a derived class naturally might call the output method of its parent(s):
class Derived: public Base
//...
virtual std::ostream& output(std::ostream& os) const
{
Base::output(os);
return os << my_specific_data;
}
};

lightweight boost::bind

I'm so sick of the pass-callback-data-as-void*-struct anti-pattern. Boost bind solves it nicely, but is an unacceptable dependency. What's a lightweight alternative? How would I write it myself as simply as possible?
First, I question your assertion that it's far too heavy for you to use.
Second, roll your own template, if you need to control the behavior.
Third, if you're afraid of rolling your own template, I question your ability to judge that boost::bind is too heavy for you to use.
Check out the fast delegate by Don Clugston. It's supposedly the fastest delegate you can find on most current platforms (compiles down to 2 assembly instructions.) Version 1.4+ gains some Boost.Bind compatibility.
I'm not familiar with boost:bind, but is it something like this?
#include <iostream>
void foo (int const& x) {
std::cout << "x = " << x << std::endl;
}
void bar (std::string const& s) {
std::cout << "s = " << s << std::endl;
}
template<class T>
void relay (void (*f)(T const&), T const& a) {
f(a);
}
int main (int argc, char *argv[])
{
std::string msg("Hello World!");
relay (foo, 1138);
relay (bar, msg);
}
Output --
x = 1138
s = Hello World!
Boost.Function improved performance dramatically as of around 1.34 when used together with boost::bind. If you profiled with an old boost version, maybe do it again with a more recent one. boost::function got the ability to save small function objects in a small buffer allocated on the stack, instead of on the heap (using placement new).
See this mailing list message: http://lists.boost.org/Archives/boost/2006/01/98993.php.
A common C++ idiom is to use functors (i.e. objects that override operator()). The point is that you use a single object to encapsulate both the code to be called back, and the data on which that code will act. Whether the functor is hand-rolled, or generated using boost::bind and/or <functional>, probably doesn't make a whole lot of difference to runtime overhead.
So instead of:
typedef void (*cb)(void*);
void funcThatNeedsCallback(cb thecallback, void *thedata) {
// blah blah
thecallback(thedata);
}
do:
template<typename T>
void funcThatNeedsCallback(T &thefunctor) {
// blah blah
thefunctor();
}
Then the caller does:
struct MyFunctor {
int mydata1;
char *mydata2;
void operator()(void) {
// do something with mydata1 and mydata2
}
};
MyFunctor mf = { value1, value2 };
funcThatNeedsCallback(mf);
Obviously if you prefer, you can make the members private and pass them in to a constructor rather than using the initializer list.
If you're worried about templates (for instance, if funcThatNeedsCallback is a lot of code which gets duplicated), then use an abstract class to define a virtual method which the parameter must have, and use that method as the callback:
class CallbackInterface {
virtual void theCallback(void) = 0;
virtual ~CallbackInterface() {} // just in case
};
void funcThatNeedsCallback(CallbackInterface &cb) {
// blah blah
cb.theCallback();
}
There is libsigc++. The license is LGPL, but the implementation is about what Boost.Signal does (I'm reading "too heavyweight" to mean "installing all of Boost is too heavyweight" not "Boost.Signal is too slow").
People defending boost::binds speed have probably never written low latency trading systems or high speed graphics libraries.
Boost is a good general purpose library, not a speed optimised one. Some boost libraries (compared to tuned implementations) can be quite slow in comparison.
For functions/delegates, See http://www.codeproject.com/KB/cpp/fastdelegate2.aspx for a useful comparison.
Ciao.