I'm not sure if this calls for boost::any. I'd rather use native templates if there's a pattern that does what I want. I have this class (which I've written here using boost::any) defined in a header:
template <typename T> class Observable;
class Report
{
typedef unordered_map<wstring, std::shared_ptr<Observable<boost::any>>> ObservationMap;
public:
void AddObservable(const wstring& name, std::shared_ptr<Observable<boost::any>> observable);
const Observable<boost::any>& GetObservable(const wstring& name) const;
protected:
ObservationMap observations;
};
and Observable is defined like this:
template <typename T>
struct Observable
{
typedef T Type;
T Quantity;
// ...
};
I would really like some way of adding Observables of any quantity type to Reports. Is there a more effective way of doing this without incurring the overhead of boost::any?
Edit: An example of code that adds observables to the report class would be something like this:
Observable<float> obs1;
obs1.Quantity = 1.1f;
Observable<int> obs2;
obs2.Quantity = 5;
Report report;
report.AddObservable("Height", obs1);
report.AddObservable("Age", obs2);
Then somewhere else I would want to read those quantities. Say I receive the report:
void DoSomethingWithReport(Report& report)
{
float height = report.GetObservable("Height").Quantity;
int age = report.GetObservable("Age").Quantity;
}
Something like that. Of course, I'd really add other methods to check if those observations are present in the report, etc. I prefer it to be generic because I don't know beforehand, at the receiving site, what it will contain, so I'd like some flexibility.
boost::any is a decently efficient way to store a value of a type you have prevented the compiler (for whatever reason or design requirement) from knowing.
If there are only a limited set of operations you want to perform on the data, you can use type erasure instead and/or a base interface class. But that requires knowing all uses for the data when you define the interface.
If you have a limited set of data types, boost::variant or the like can be more efficient than any. You can even have a variant that includes any or a type erasure object (or objects) in the set of types.
You can use reflection or similar techniques to store complex data and wrap it in any accessors (or variant) if your data is sometimes structured, which can reduce storage overhead somewhat. Basically structured data becomes a type erased type with member access by name.
Much of these techniques end up mirroring type behaviour of scripting or bytecode languages: sometimes it might be a good idea to write the part of your app that needs this amount of compile time flexibilty in a mainly runtime type checked language.
Finally you may decide you do not need all this needless runtime dynamic typing.
Related
Sometimes I have a problem and see 3 ways of implementing the solution. I want to know when to use which of these 3 different implementations. Below there are some exsamples, to see what I mean. I also wrote some pros/kontras which I think is correct. If something seems to be wrong, then please tell me and I'll change that.
void* example:
void method(void* value)
{
//save value as member
}
pro void*:
void* can save every type and you don't have to use templates (in headers).
kontra void*:
-when you have a list of void* you can store in index[1] another type than in index[2] which is critical, because you don't know which type it is. But with dynamic_cast you can check if you can cast it to the type or not.
-when you have a void* list with entities of the same class which have 2 variables, you can not sort by variable1 / variable2 without casting it back to the original class.
Extension exsample:
Creating a new class and extent it on another class:
class CTestClass
{
void Method1();
};
class CTest2 : CTestClass
{
//use somehow the method
};
std::vector<CTestClass> list;
pro Extension:
this way of implementing a class can be usefull, if you need a method which is in every object you need. For example you want to sort by a variable. In such a method you can make the compare.
kontra Extension:
much effort
exsample template:
template <class T>
class CTest
{
//do some stuff
};
pro template:
in a template list, you can not add different types at the same time.
kontra template:
when you have a template list of type T and T has for exsample 2 variables. You can not say: sort by variable1 or variable2 because you can not get into the class T.
As far as I know: you have to implement the template into the header file, which is ugly to see.
I hope everyone understands what I mean.
Is void* a good way to program?
Can I write templates also in .cpp files?
What do you think when to use which of this techniques? Is there some kind of rule?
The statement below is incorrect
pro void*:
void* can save every type and you don't have to use templates (in
headers).
Templates haver their closest equivalent in cross macros and not in void pointers, but exist for a different set of purposes than the mere polymorphism afforded by void pointers. Using void pointers in no way substitutes templates.
While modern programmers might not recommend about using void pointers, complaining about the (true!) potential dangers afforded, old school C-style code certainly has a use for them and this is the reason they exist. Pairing the benefits gained from void pointers with the tradeoff in performance by the C++ dynamic cast, would simply spoil the choice.
Void pointers just exist to offer limitless flexibility at managing memory when you know what you are doing and should be used only in that case. There is no comparison between them and templates.
A method that takes a void * argument should only exist when:
Case 1: The size of the passed data is known and the argument is considered as raw data. It makes no difference what that data is.
Case 2: The size of the passed data is known and you plan to convert it to a pointer of the appropriate type later (for example by some parsing, enumeration policy, known type, etc) but in order to go through some general purpose functions, libraries, APIs, you must convert it to known-length void* inbetween.
Using polymorphism in C++ usually requires dynamic allocation, use of the factory pattern, etc. Is that not a true statement? Sure, I can instantiate a derived type on the stack if I really try, but is that every day code or an academic exercise?
Some other object orientated languages allocate every user made type on the heap. However, any allocation in C++ us likely to raise debates over performance with your peers.
How then, are you to use polymorphism while keeping allocation to a minimum?
Also, are we really writing real world code while using polymorphism without any dynamic allocation? Are we to forget we ever learned the factory pattern?
Edit:
It seems to me in this Q&A that we have identified a difference between scenarios where the type is known at compile time or it isn't.
It has been brought up that the use of streams are an example of polymorphism without dynamic allocation. However, when you are using streams, you know the type you need as you are typing out your program.
On the other hand, there are the scenarios where you don't know the type at compile time. This is where I reach (and have been taught to reach) for the factory pattern. Given some input, decide what concrete type to instantiate. I don't see any alternative to this. Is there one?
--
Let's try to use a scenario that came up in real world code.
Let us assume a stock trading system.
Your job is to store orders that arrive over the network from customers.
Your input is JSON text.
Your output should be a collection of data structures representing the orders
An order could be a vanilla stock purchase, an Option, or a Future.
You do not know what customers are ordering until you parse the JSON
Naturally, I'd come up with something like this, super simplified for purposes of example, domain:
class Order
{
protected:
double m_price;
unsigned m_size;
};
class Option : public Order
{
protected:
string m_expirationDate;
};
class Future : public Order
{
protected:
string m_expirationDate;
};
And then I'd come up with some factory that parses the JSON and spits out an order:
class OrderFactory
{
Order * CreateOrder(const std::string & json);
};
The factory allocates. Therefore, your peers are likely to point out that it's slow in a system that receives millions of orders per second.
I suppose we could convert our domain to some C like monstrosity:
struct Order
{
enum OrderType
{
ORDER_TYPE_VANILLA,
ORDER_TYPE_OPTION,
ORDER_TYPE_FUTURE
}
OrderType m_type;
double m_price;
unsigned m_size;
std::string m_expirationDate; // empty means it isnt used
int m_callOrPut // Encoder rings are great for code!
// -1 - not used
// 0 - Put
// 1 - Call
};
but then we are just ditching polymorphism, and what I think are good OO principles, altogether. We'd still, most likely be allocating these and storing them as they came in too. Unless we want to declare some statically sized container for them and mark elements used or un-used....(yet more C)
Is there some alternative that would not allocate that I am not aware of?
Using polymorphism in C++ usually requires dynamic allocation, use of
the factory pattern, etc. Is that not a true statement? Sure, I can
instantiate a derived type on the stack if I really try, but is that
every day code or an academic exercise?
"Usually" is a bit meaningless; it's a fuzzy comparison on which there are no metrics to produce statistics. Is it possible to use polymorphism without dynamic allocation? Yes, trivially. Consider this case:
struct A{};
struct B : A;
void foo(A& a) {};
void foo(A* a) {};
void bar() {
B b;
foo(b);
foo(&b);
}
and no dynamic memory used.
First off, in C++ people often distinguish compile-time and run-time polymorphis, I take it, your question is about run-time polymorphic behavior.
Yes, there are ways to enjoy polymorphism without using dynamic allocation. A good example of such are streams in STL. (Although, a lot of people question their design, but that's beside the point).
There are people who say that unless you have a container of (pointers to) polymorphic objects of different dynamic types, run-time polymorphism is really not needed and templates would work better - but since templates comes at their own cost, sometimes run-time polymorphism is suited better.
I often run into the problems associated with SubType Polymorphism, I'm looking for an elegant solution I may not already be aware of.
Here is a simple inheritence hierarchy:
struct BaseClass {
virtual ~BaseClass() = 0;
std::string name;
};
template <T>
struct DerivedClass
{
DerivedClass(const std::string& _name): name(_name) { }
};
Now I might create lots of these DerivedClass instances with different names and template types and store them in an array using their BaseClass.
std::vector<BaseClass*> array;
array.push_back(new DerivedClass<TABC>("abc"));
array.push_back(new DerivedClass<TDEF>("def"));
...
This is pretty standard runtime polymorphism.
However, when I have a new layer of functionality that is type-specific to add and don't want this new layer to be coupled in both directions, I end up having to do something like this:
template <typename T>
void method(DerivedClass<T>* object) { }
void callMethod(BaseClass* object)
{
// this is the logic I'm trying to move up a layer
if (object->name == "abc") method<TABC>(object);
else if (object->name == "def") method<TDEF>(object);
}
Each of these methods has to have the same list of run-time strings to compile-time types to convert, which means adding a new type requires a lot of changes.
If I was to assume the new layer would only support specific options known at compile-time (as is the case here anyway), then it would be feasible to add new types at runtime, but not be able to use them in this layer, which would be fine.
My current thinking is if I was to introduce a virtual method to the class hierarchy that took a function pointer, I could register the function pointers for each method in the second layer based on specific compile-time types (ideally only specified once), kind of like a double dispatch type method.
Any thoughts, suggestions?
You need that link to call the specific template version based on a string, the best you can do is have a dictionary of string->lambda function and use the string as a lookup to get a function<> to call. This avoids the nested ifs and it's relatively easy to maintain, both at compile time (the default list) and at runtime (any changes are just array changes).
Rather than steal Sean Parent's thunder I'll direct you to this talk which will show you how to achieve this cleanly, safely and simply.
The technique is called 'polymorphism as an implementation detail'. It has transformed the way I write code.
https://channel9.msdn.com/Events/GoingNative/2013/Inheritance-Is-The-Base-Class-of-Evil
Given the following, working code.
#include <iostream>
template<class Detail>
class AbstractLogger
{
public:
static void log(const char* str) {
Detail::log_detailled(str);
}
};
class Logger : public AbstractLogger<Logger>
{
public:
static void log_detailled(const char* str) {
std::cerr << str << std::endl;
}
};
int main(void)
{
AbstractLogger<Logger>::log("main function running!");
return 0;
}
Now, I want to put AbstractLogger into a library, and let the library user define his own logger, like the Logger class here. This has one drawback: AbstractLogger<Logger> can not be used inside the library, since the library can not know Logger.
Notes:
Please no virtual functions or questions why not. Also, I am aware of the similar problem that "static virtual" members are invalid. Maybe, there is a workaround in CRTP :)
C++11 will be interesting, however, I need "usual" C++.
If what you mean is that you want to have a library that uses this as a logging mechanism without knowing the exact instantiating type, I would advice against it.
The only way of doing it while meeting your other requirements (i.e. no virtual functions) is that all your functions/types in the library that need to log are converted into templates that take the Logger type. The net result is that most of your interface becomes a template (although you can probably move a good amount of the implementation to non-templated code, it will make your life much harder than needed, and it will still generate a much larger binary).
If your concern with virtual functions is performance, then you should reconsider your approach and the problems it brings. In particular, logging is expensive. Most logging libraries tackle it by optimizing the non-logging case (by means of macros that avoid calling the logger if the log level/group/... are not enabled), but still leave dynamic dispatch for the actual writting. The cost of the dynamic dispatch is negligible compared with the cost of writing to the console, or a file, or even with the cost of generating the message that will be logged (I am assuming that you not only log literal strings)
The usual approach is to code against a concept, while providing helpers so that users may easily produce types that satisfy one or more of those concepts. As an example, something like boost::iterator_facade is a CRTP helper that makes it easier for a user to write an iterator. Then, that iterator can be used anywhere an iterator is accepted -- for instance in the range constructor of std::vector. Notice how that particular constructor has no foreknowledge of the user-defined type.
In your case, AbstractLogger would be the CRTP helper. The missing piece would be to define e.g. a logger concept. As a result, notice that everything that needs a logger either needs to be implemented as a template or you need a type-erasing container to hold arbitrary loggers.
Concept checks (like those provided by Boost) are convenient for this kind of programming, since they allow to represent a concept with actual code.
Template classes can't be 'put in a library' since they are instantiated by the compiler as specializations of their template parameters.
You may put parameter independent stuff used in the template implementation into a library though.
I am running a simulation in which I have objects of a class which use different models. These models are randomly selected for some objects of the class and specifically decided for some objects too. These objects communicate with each other for which I am using structures (aka struct) in C++ which has some
standard variables and
some additional variables which depends on models which the objects communicating with each other have.
So, how can I do this?
Thanks in advance.
You can hack around with:
the preprocessor;
template meta-programming;
inheritance/polymorphism.
Each gives a different way of producing a different user-defined type, based on different kinds of conditions.
Without knowing what you're trying to accomplish, this is the best I can do.
All instances of a structure or class have the same structure. Luckily, there are some tricks that can be used to 'simulate' what you try to do.
The first trick (which can also be used in C), is to use a union, e.g.:
struct MyStruct
{
int field1;
char field2;
int type;
union
{
int field3a;
char field3b;
double field3c;
} field3;
};
In a union, all members take up the same space in memory. As a programmer you have to be careful. You can only get out of the union what you put in. If you initialize one member of a union, but you read another member, you will probable get garbage (unless you want to do some low-level hacks, but don't do this unless you are very experienced).
Unions often come together with another field (outside the union) that indicates which member is actually used in the union. You could consider this your 'condition'.
A second trick is use the 'state' pattern (see http://en.wikipedia.org/wiki/State_pattern). From the outside world, the context class looks always the same, but internally, the different states can contain different kinds of information.
A somewhat simplified approach for state is to use simple inheritance, and to use dynamic casts. Depending on your 'condition', use a different subclass, and perform a dynamic cast to get the specific information.
E.g., suppose that we have a Country class. Some countries have a president, others have a king, others have an emperor. You could something like this:
class Country
{
...
};
class Republic : public Country
{
public:
const string &getPresident() const;
const string &getVicePresident() const;
};
class Monarchy : public Country
{
public:
const string &getKing() const;
const string &getQueen() const;
};
In your application you could work with pointers to Country, and do a dynamic cast to Republic or Monarchy where the president or king is needed.
This example can be easily transformed into one using the 'state' pattern, but I leave this as an exercise for you.
Personally, I would go for the state pattern. I'm not a big fan of dynamic casts and they always seem to be kind-of-hack for me.
If it's at compile-time, a simple #ifdef or template specialization will serve this purpose just fine. If it's at run-time and you need value semantics, you can use a boost::optional<my_struct_of_optional_members>, and if you're fine with reference semantics, inheritance will solve the problem at hand.
A union and that kind of dirty trick is not necessary.
There are several common approaches for "dynamic" attributes/properties in languages, and a few that tend to work well in C++.
For example, you can make a C++ class called "MyProperties" that has a sparse set of values, and your MyStructureClass would have its well-known members, plus a single MyProperties instance which may have zero-or-more values.
Similarly, languages like Python and Perl make extensive use of Associative Arrays/Dictionaries/Hashes to achieve this: The (string) key uniquely identifies the value. In C++, you can index your MyProperties class with a string or any type you want (after overloading the operator[]()), and the value can be a string, a MyVariant, or any other pointer-or-type that you want to inspect. The values are dynamically added to the parent container as they are assigned (e.g., the class "remembers" the last value it is given, uniquely identified by key).
Finally, in the "olden days", what you describe was commonly done for distributed application processing: You defined a C-struct with "well-known" (typed) fields/members, and the last field was a char* member. Then, that char* member would identify the start of a serialized stream of bytes that were also part of that struct (you merely serialized that array of chars when you marshalled the struct across systems). In the context of C++, you could similarly extract your values dynamically from that char* stream buffer on-access-demand (which logically should be "owned" by the class). This worked for marshalling across systems because the size of the struct was the size of everything (including the last char* member), but the "allocation" for that struct was much larger (e.g., the size of the struct itself, which was logically a "header", plus a certain number of bytes after that header, which represented the "payload" and which was indexed by the last member, the char* member.) Thus, it was a contiguous-block-of-memory struct, with dynamic size. (This would also work in C++ as long as you passed-by-reference, and never by value.)
embed an union into your structure, and use a flag to tell which part of the union is valid.
enum struct_type
{
cool,
fine,
bad
};
struct demo
{
struct_type type;
union
{
struct
{
double cool_factor;
} cool_part;
struct
{
int fineness;
} fine_part;
struct
{
char *bad_stuff;
} bad_part;
};
struct
{
int life_is_cool;
} common_part;
};
The pure and simple C++ answer is: use classes.
I can't determine from your question what you are trying to achieve: runtime variation or compile time variation, but either way, I doubt you'll get a workable implementation any other way. (Template metaprogramming aside... which isn't for the faint of heart.)