Could someone help me create a variable container using Boost::MPL? - c++

I have created a physics system that handles any collision object to any collision object like so:
namespace Collision
{
template <typename T, typename U>
inline void Check(T& t, U& u)
{
if(u.CheckCollision(t.GetCollider()))
{
u.HitBy(t);
t.Hit(u);
}
}
}
and there are several other helper objects to make it easy to use, but the gist is that there are dynamic objects that need to be tested against static objects and other dynamic objects, but static objects don't need to be checked.
What I would like is something like this:
void func()
{
PhysicsWorld world;
shared_ptr<CSphere> ballPhysics(new CSphere(0,0,ballSprite->Width()));
BallCommand ballBehavior;
CBounds bounds(0, 0, 640, 480);
CBox obstacle(200, 150, 10, 10);
Collision::Collidable<CBounds> boundC(bounds);
Collision::Collidable<std::shared_ptr<CSphere>, BallCommand&> ballC(ballPhysics, ballBehavior);
Collision::Collidable<CBox> obstC(obstacle);
world.addStatic(boundC);
world.addDynamic(ballC);
world.addStatic(obstC);
...
...
world.Update();
...
...
}
I'd love to deduce the containers through the add functions so using the system automatically updates the type lists. I think I get how to generate a typelist with a template function, but not how to then get it where I need it, or at what point in compilation it is complete.
If not that then some system using two typelists that then internally writes the update function to iterate through all the lists pairing them up against each other.
I've read some of the boost MPL book and read Andrei's book several times. But, I seem to get caught up in the how it works stuff and don't really translate that into how do I use it. I wish they had one more section on real world examples in the MPL book.
I've been able to get all of the pieces of a game engine to interact with rendering, physics, collisions (I separate detection from reaction), input, network, sound, etc. All in generic ways. Now I just need to hold all the things in a generic way. After all that generic work, it would be silly to require inheritance just so I can hold something in a container and I don't want to hand code every collection possibility as that is one of the great benefits of generic programming.
I saw Jalf had indicated that s/he used MPL to do something similar, but did not go into details enough for me to figure it out. If anyone knows a practical use example or where I can get more info on using the MPL I'd be grateful.
Thanks again!
Update
boost MPL and boost Fusion both seem to do what I want, but there appears to be very little in the way of good real life examples of either libraries. The documentation for MPL is little more than this template does this and good luck understanding the implications of that. Fusion is a bit better with "Here's an example but it's just the tip of the iceberg!"
A typical boost MPL example is has_xxx. They use XXX and xxx in the example making it difficult to see the difference where XXX(The required text) and Test or CheckType or any more distinguishable user type could be used in place of xxx. Plus there is no mention that none of this is in a namespace. Now I know why Scott meyers compared this to the shower scene in Psycho.
It's a shame really because what little I have gotten to compile and understand does really useful things, but is so hard to figure out I would never spend this much effort if I was on a shipping product.
If anyone knows real world examples or better references, explanations, or tutorial I would be grateful.
Update
Here's more code:
template <typename T, typename V = VictimEffect, typename M = MenaceEffect>
class Collidable
{
T m_Collider;
V m_HitBy;
M m_Hit;
public:
Collidable(T collide, V victim, M menace) : m_Collider(collide), m_HitBy(victim), m_Hit(menace) {;}
Collidable(T collide) : m_Collider(collide) {;}
Collidable(T collide, V victim) : m_Collider(collide), m_HitBy(victim) {;}
T& GetCollider()
{
return m_Collider;
}
template <typename V>
void HitBy(V& menace)
{
m_HitBy.HitBy(menace.GetCollider());
}
template <typename V>
void Hit(V& victim)
{
m_Hit.Hit(victim.GetCollider());
}
template <typename V>
bool CheckCollision(V& menace)
{
return m_Collider.CheckCollision(menace);
}
};
Then to use it I do this
Collidable<Boundary, BallCommand> boundC(boundary, ballBehavior);
Collidable<CollisionBox> ballC(circle);
Then all I need is to call collide with all my active collidable objects against all my active and passive objects.
I'm not using std::function because the addition of function names makes the code clearer to me. But maybe that's just legacy thinking.

If I understand correctly your problem is:
class manager {
public:
template<typename T>
void add(T t);
private:
/* ??? */ data;
/* other members? */
};
manager m;
some_type1 s1;
some_type2 s2;
m.add(s1);
m.add(s2);
/* m should hold its copies of s1 and s2 */
where some_type1 and some_type2 are unrelated and you're unwilling to redesign them to use dynamic polymorphism.
I don't think either MPL or Fusion will do what you want with this form. If your problem is what container to use as a member of PhysicsWorld, then no amount of compile-time computations will help: the member type is determined at instantiation time, i.e. the line manager m;.
You could rewrite the manager in a somewhat meta-programing fashion to use it this way:
typedef manager<> m0_type;
typedef typename result_of::add<m0_type, some_type1>::type m1_type;
typedef typename result_of::add<m1_type, some_type2>::type final_type;
/* compile-time computations are over: time to instantiate */
final_type m;
/* final_type::data could be a tuple<some_type1, some_type2> for instance */
m.add(s1); m.add(s2);
This is indeed the sort of things MPL+Fusion can help with. However this still remains quite anchored in the compile-time world: can you imagine writing an template<typename Iter> void insert(Iter first, Iter last) just so you can copy the contents of a container into a manager?
Allow me to assume that your requirements are such that in fact the manager has to be used in a much more runtimey fashion, like in my original formulation of your question. (I don't think that's quite a stretch of the imagination for a PhysicsWorld). There is an alternative, which I think is more appropriate, much less verbose and more maintanable: type-erasure. (The name of the technique may be a bit unfortunate and can be misleading the first time.)
A good example of type-erasure is std::function:
std::function<void()> func;
func = &some_func; /* this just looks like that internally std::function stores a void(*)() */
func = some_type(); /* but here we're storing a some_type! */
Type-erasure is a technique to bridge compile-time with runtime: in both assignments above, the arguments are unrelated types (one of which is non-class so not even remotely runtime polymorphic), but std::function handles both, provided they fulfill the contract that they can be used as f() (where f is an instance of the respective type) and that the expression has type (convertible to) void. The contract here is the compile-time aspect of type-erasure.
I'm not going to demonstrate how to implement type-erasure because there is a great Boostcon 2010 presentation on the subject. (You can watch the presentation and/or get the slides through the link). Or I (or someone else) can do it in the comments.
As a final note, implementation of type-erasure (typically) uses dynamic polymorphism. I mention that because I noticed you considered the use of typelists as a runtime object stored as a manager member. This smells like poor man's reflection, and really, poor man's dynamic polymorphism. So don't do that please. If you meant typelists as in the result of a MPL computation then disregard the node.

This is not complete And I did not get everything I want, but it's good enough for now. I'm entering the whole solution in case it helps others.
#include <boost\mpl\vector.hpp>
#include <boost\mpl\fold.hpp>
#include <boost\mpl\for_each.hpp>
#include <boost\mpl\inherit.hpp>
#include <boost\mpl\inherit_linearly.hpp>
#include <iostream>
#include <vector>
using namespace boost::mpl::placeholders;
typedef boost::mpl::vector<short, long, char, int> member_types;
template <typename T>
struct wrap
{
std::vector<T> value;
};
typedef boost::mpl::inherit_linearly<member_types, boost::mpl::inherit<wrap<_2>, _1> >::type Generate;
class print
{
Generate generated;
public:
template <typename T>
void operator()(T)
{
std::cout << *static_cast<wrap<T>&>(generated).value.begin() << std::endl;
}
template <typename T>
void Add(T const& t)
{
static_cast<wrap<T>&>(generated).value.push_back(t);
}
};
void main()
{
print p;
short s = 5;
p.Add(s);
long l = 555;
p.Add(l);
char c = 'c';
p.Add(c);
int i = 55;
p.Add(i);
boost::mpl::for_each<member_types>(p);
}
This isn't the final object I need, but now I have all the pieces to make what I want.
Update
And finally I get this.
template <typename TL>
class print
{
template <typename T>
struct wrap
{
std::vector<T> value;
};
typedef typename boost::mpl::inherit_linearly<TL, boost::mpl::inherit<wrap<_2>, _1> >::type Generate;
Generate generated;
public:
void Print()
{
boost::mpl::for_each<TL>(*this);
}
template <typename T>
void operator()(T)
{
std::cout << *static_cast<wrap<T>&>(generated).value.begin() << std::endl;
}
template <typename T>
void Add(T const& t)
{
static_cast<wrap<T>&>(generated).value.push_back(t);
}
};
Here TL is a boost::mpl container of what types should be held.
I think that provides a good starting point for expanding, but covers much of the metaprogramming parts.
I hope this helps others.

Related

What realization to choose for heterogenous container that uses std::variant for data storage?

For a program which is a simple rogue-like game, I need a container for storing contents of each room be it enemies, loot, traps, lore-entries etc. Since set of types being held in each room is finite and predetermined I've settled for std::variant for data storage. I also will need methods to process the data and here comes the problem. Now due to lack of experience I struggle to choose realization that won't become a burden in long term.
Objective style approach:
using myVariant = std::variant<TYpe1, Type2 ... TypeN>;
template <typename V>
class HVector
{
private:
class HVElem
{
private:
V data;
public:
V getData();
};
std::vector<HVElem> content;
public:
void push(V newData);
};
int main()
{
HVector<myVariant> hVector;
}
Functional approach:
using myVariant = std::variant<TYpe1, Type2 ... TypeN>;
template <typename V> void push(std::vector<V> hVector, V newData)
{
// something
}
int main()
{
std::vector hVector<myVariant>;
}
Questions:
Which of the two approaches is better? I have a strong feeling that simply using std::vector<std::variant<>> with some template functions is enough in this case. Is using objective style even requiered here?
How can I prevent the program from creating a container that holds anything other than std::variant<>? Is there a way to simply list types in type aliases so that I could simply write std::vector<std::variant<myTypes>>?
Which of the two approaches is better?
Neither, see option 3 below.
How can I prevent the program from creating a container that holds anything other than std::variant<>?
using myVariant = std::variant<TYpe1, Type2 ... TypeN>;
using myVector = std::vector<myVariant>;

What is the "correct OOP" way to deal with a storage pool of items of mixed types?

This was inspired by a comment to my other question here:
How do you "not repeat yourself" when giving a class an accessible "name" in C++?
nvoight: "RTTI is bad because it's a hint you are not doing good OOP. Doing your own homebrew RTTI does not make it better OOP, it just means you are reinventing the wheel on top of bad OOP."
So what is the "good OOP" solution here? The problem is this. The program is in C++, so there are also C++ specific details mentioned below. I have a "component" class (actually, a struct), which is subclassed into a number of different derived classes containing different kinds of component data. It's part of an "entity component system" design for a game. I'm wondering about the storage of the components. In particular, the current storage system has:
a "component manager" which stores an array, actually a hash map, of a single type of component. The hash map allows for lookup of a component by the entity ID of the entity it belongs to. This component manager is a template which inherits from a base, and the template parameter is the type of component to manage.
a full storage pack which is a collection of these component managers, implemented as an array of pointers to the component manager base class. This has methods to insert and extract an entity (on insertion, the components are taken out and put into the managers, on removal, they are extracted and collected into a new entity object), as well as ones to add new component managers, so if we want to add a new component type to the game, all we have to do is put another command to insert a component manager for it.
It's the full storage pack that prompted this. In particular, it offers no way of accessing a particular type of component. All the components are stored as base class pointers with no type information. What I thought of was using some kind of RTTI and storing the component managers in a map which maps type names and thus allows for lookup and then the proper downcasting of the base class pointer to the appropriate derived class (the user would call a template member on the entity storage pool to do this).
But if this RTTI means bad OOP, what would be the correct way to design this system so no RTTI is required?
Disclaimer/resources: my BCS thesis was about the design and implementation of a C++14 library for compile-time Entity-Component-System pattern generation. You can find the library here on GitHub.
This answer is meant to give you a broad overview of some techniques/ideas you can apply to implement the Entity-Component-System pattern depending on whether or not component/system types are known at compile-time.
If you want to see implementation details, I suggest you to check out my library (linked above) for an entirely compile-time based approach. diana is a very nice C library that can give you an idea of a run-time based approach.
You have several approaches, depending on the scope/scale of your project and on the nature of your entities/components/systems.
All component types and system types are known at compile-time.
This is the case analyzed in my BCS thesis - what you can do is use advanced metaprogramming techniques (e.g. using Boost.Hana) to put all component types and system types in compile-time lists and create data structures that link everything together at compile time. Pseudocode example:
namespace c
{
struct position { vec2f _v };
struct velocity { vec2f _v };
struct acceleration { vec2f _v };
struct render { sprite _s; };
}
constexpr auto component_types = type_list
{
component_type<c::position>,
component_type<c::velocity>,
component_type<c::acceleration>,
component_type<c::render>
};
After defining your components, you can define your systems and tell them "what components to use":
namespace s
{
struct movement
{
template <typename TData>
void process(TData& data, float ft)
{
data.for_entities([&](auto eid)
{
auto& p = data.get(eid, component_type<c::position>)._v;
auto& v = data.get(eid, component_type<c::velocity>)._v;
auto& a = data.get(eid, component_type<c::acceleration>)._v;
v += a * ft;
p += v * ft;
});
}
};
struct render
{
template <typename TData>
void process(TData& data)
{
data.for_entities([&](auto eid)
{
auto& p = data.get(eid, component_type<c::position>)._v;
auto& s = data.get(eid, component_type<c::render>)._s;
s.set_position(p);
some_context::draw(s);
});
}
};
}
constexpr auto system_types = type_list
{
system_type<s::movement,
uses
(
component_type<c::position>,
component_type<c::velocity>,
component_type<c::acceleration>
)>,
system_type<s::render,
uses
(
component_type<c::render>
)>
};
All that's left is using some sort of context object and lambda overloading to visit the systems and call their processing methods:
ctx.visit_systems(
[ft](auto& data, s::movement& s)
{
s.process(data, ft);
},
[](auto& data, s::render& s)
{
s.process(data);
});
You can use all the compile-time knowledge to generate appropriate data structures for components and systems inside the context object.
This is the approach I used in my thesis and library - I talked about it at C++Now 2016: "Implementation of a multithreaded compile-time ECS in C++14".
All component types and systems types are known at run-time.
This is a completely different situation - you need to use some sort of type-erasure technique to dynamically deal with components and systems. A suitable solution is using a scripting language such as LUA to deal with system logic and/or component structure (a more efficient simple component definition language can also be handwritten, so that it maps one-to-one to C++ types or to your engine's types).
You need some sort of context object where you can register component types and system types at run-time. I suggest either using unique incrementing IDs or some sort of UUIDs to identify component/system types. After mapping system logic and component structures to IDs, you can pass those around in your ECS implementation to retrieve data and process entities. You can store component data in generic resizable buffers (or associative maps, for big containers) that can be modified at run-time thanks to component structure knowledge - here's an example of what I mean:
auto c_position_id = ctx.register_component_type("./c_position.txt");
// ...
auto context::register_component_type(const std::string& path)
{
auto& storage = this->component_storage.create_buffer();
auto file_contents = get_contents_from_path(path);
for_parsed_lines_in(file_contents, [&](auto line)
{
if(line.type == "int")
{
storage.append_data_definition(sizeof(int));
}
else if(line.type == "float")
{
storage.append_data_definition(sizeof(float));
}
});
return next_unique_component_type_id++;
}
Some component types and system types are known at compile-time, others are known at run-time.
Use approach (1), and create some sort of "bridge" component and system types that implements any type-erasure technique in order to access component structure or system logic at run-time. An std::map<runtime_system_id, std::function<...>> can work for run-time system logic processing. An std::unique_ptr<runtime_component_data> or an std::aligned_storage_t<some_reasonable_size> can work for run-time component structure.
To answer your question:
But if this RTTI means bad OOP, what would be the correct way to design this system so no RTTI is required?
You need a way of mapping types to values that you can use at run-time: RTTI is an appropriate way of doing that.
If you do not want to use RTTI and you still want to use polymorphic inheritance to define your component types, you need to implement a way to retrieve some sort of run-time type ID from a derived component type. Here's a primitive way of doing that:
namespace impl
{
auto get_next_type_id()
{
static std::size_t next_type_id{0};
return next_type_id++;
}
template <typename T>
struct type_id_storage
{
static const std::size_t id;
};
template <typename T>
const std::size_t type_id_storage<T>::id{get_next_type_id()};
}
template <typename T>
auto get_type_id()
{
return impl::type_id_storage<T>::id;
}
Explanation: get_next_type_id is a non-static function (shared between translation units) that stores a static incremental counter of type IDs. To retrieve the unique type ID that matches a specific component type you can call:
auto position_id = get_type_id<position_component>();
The get_type_id "public" function will retrieve the unique ID from the corresponding instantiation of impl::type_id_storage, that calls get_next_type_id() on construction, which in turn returns its current next_type_id counter value and increments it for the next type.
Particular care for this kind of approach needs to be taken to make sure it behaves correctly over multiple translation units and to avoid race conditions (in case your ECS is multithreaded). (More info here.)
Now, to solve your issue:
It's the full storage pack that prompted this. In particular, it offers no way of accessing a particular type of component.
// Executes `f` on every component of type `T`.
template <typename T, typename TF>
void storage_pack::for_components(TF&& f)
{
auto& data = this->_component_map[get_type_id<T>()];
for(component_base* cb : data)
{
f(static_cast<T&>(*cb));
}
}
You can see this pattern in use in my old and abandoned SSVEntitySystem library. You can see an RTTI-based approach in my old and outdated “Implementation of a component-based entity system in modern C++” CppCon 2015 talk.
Despite the good and long answer by #VittorioRomeo, I'd like to show another possible approach to the problem.
Basic concepts involved here are type erasure and double dispatching.
The one below is a minimal, working example:
#include <map>
#include <vector>
#include <cstddef>
#include <iostream>
#include <memory>
struct base_component {
static std::size_t next() noexcept {
static std::size_t v = 0;
return v++;
}
};
template<typename D>
struct component: base_component {
static std::size_t type() noexcept {
static const std::size_t t = base_component::next();
return t;
}
};
struct component_x: component<component_x> { };
struct component_y: component<component_y> { };
struct systems {
void elaborate(std::size_t id, component_x &) { std::cout << id << ": x" << std::endl; }
void elaborate(std::size_t id, component_y &) { std::cout << id << ": y" << std::endl; }
};
template<typename C>
struct component_manager {
std::map<std::size_t, C> id_component;
};
struct pack {
struct base_handler {
virtual void accept(systems *) = 0;
};
template<typename C>
struct handler: base_handler {
void accept(systems *s) {
for(auto &&el: manager.id_component) s->elaborate(el.first, el.second);
}
component_manager<C> manager;
};
template<typename C>
void add(std::size_t id) {
if(handlers.find(C::type()) == handlers.cend()) {
handlers[C::type()] = std::make_unique<handler<C>>();
}
handler<C> &h = static_cast<handler<C>&>(*handlers[C::type()].get());
h.manager.id_component[id] = C{};
}
template<typename C>
void walk(systems *s) {
if(handlers.find(C::type()) != handlers.cend()) {
handlers[C::type()]->accept(s);
}
}
private:
std::map<std::size_t, std::unique_ptr<base_handler>> handlers;
};
int main() {
pack coll;
coll.add<component_x>(1);
coll.add<component_y>(1);
coll.add<component_x>(2);
systems sys;
coll.walk<component_x>(&sys);
coll.walk<component_y>(&sys);
}
I tried to be true to the few points mentioned by the OP, so as to provide a solution that fits the real problem.
Let me know with a comment if the example is clear enough for itself or if a few more details are required to fully explain how and why it works actually.
If I understand correctly, you want a collection, such as a map, where the values are of different type, and you want to know what type is each value (so you can downcast it).
Now, a "good OOP" is a design which you don't need to downcast. You just call the mothods (which are common to the base class and the deriveratives) and the derived class performs a different operation than its parent for the same method.
If this is not the case, for example, where you need to use some other data from the child and thus you want to downcast, it means, in most cases, you didn't work hard enough on the design. I don't say it's always possible, but you need to design it in such a way the polymorphism is your only tool. That's a "good OOP".
Anyway, if you really need to downcast, you don't have to use RTTI. You can use a common field (string) in the base class, that marks the class type.

Static duck typing in C++

C++ has some sort of duck typing for types given by template parameters. We have no idea what type DUCK1 and DUCK2 will be, but as long as they can quack(), it will compile and run:
template <class DUCK1, class DUCK2>
void let_them_quack(DUCK1* donald, DUCK2* daisy){
donald->quack();
daisy->quack();
}
But it's a bit inconvenient to write. When I do absolutely not care what actual types DUCK1 and DUCK2 are but rather want to fully use the idea of duck typing, then I would like to have something sligthly different than above:
I'd like to omit writing a template parameter list that is repetitive and mostly meaningless (Just imagine what would happen if there are 7 ducks...)
I'd like to make it a bit more explicit that the types are never used and that it's only the interface that matters.
I'd like to have sort of an interface annotation/check. Make somehow clear what interface is expected behind the type. (That's, however, a bit in contrast of duck typing.)
Does C++ offer any features to achieve one or more of the 3 ideas?
(I know that virtual inheritance is the method of choice in most cases to implement such patterns, but the question here is specifically about the case of static polymorphism.)
Concerning questions 1 and 2: since C++14 you can omit explicit template <typename ... boilerplate and use auto, but only in lambdas:
auto let_them_quack = [] (auto & donald, auto & daisy){
donald.quack();
daisy.quack();
};
(yes, I prefer references to pointers). GCC allows to do so in usual functions as an extension.
For the question 3, what you are talking about are called concepts. They existed in C++ for a long time, but only as a documentational term. Now the Concepts TS is in progress, allowing you to write something like
template<typename T>
concept bool Quackable = requires(T a) {
a.quack();
};
void let_them_quack (Quackable & donald, Quackable & daisy);
Note that it is not yet C++, only a technical specification in progress. GCC 6.1 already seems to support it, though. Implementations of concepts and constraints using current C++ are possible; you can find one in boost.
I'd like to omit writing a template parameter list that is repetitive
and mostly meaningless (Just imagine what would happen if there are 7
ducks...)
For that you could use variadic templates and do something like the following:
template<typename DUCK>
void let_them_quack(DUCK &&d) {
d.quack();
}
template<typename DUCK, typename... Args>
void let_them_quack(DUCK &&d, Args&& ...args) {
d.quack();
let_them_quack(std::forward<Args>(args)...);
}
Live Demo
#2 and #3 are sort of taken care of by the fact that the code will not compile, and throw a compilation error, if the given classes don't implement the interface. You could also make this formal:
class duck {
public:
virtual void quack()=0;
};
Then declare the parameters to the function as taking a pointer to a duck. Your classes will have to inherit from this class, making the requirements for let_them_quack() crystal clear.
As far as #1 goes, variadic templates can take care of this.
void let_them_quack()
{
}
template <typename ...Args>
void let_them_quack(duck* first_duck, Args && ...args) {
first_duck->quack();
let_them_quack(std::forward<Args>(args)...);
}
You will be able to make it look preetier with concept (not yet in standard - but very close):
http://melpon.org/wandbox/permlink/Vjy2U6BPbsTuSK3u
#include <iostream>
template<typename T>concept bool ItQuacks(){
return requires (T a) {
{ a.quack() } -> void;
};
}
void let_them_quack2(ItQuacks* donald, ItQuacks* daisy){
donald->quack();
daisy->quack();
}
struct DisneyDuck {
void quack(){ std::cout << "Quack!";}
};
struct RegularDuck {
void quack(){ std::cout << "Quack2!";}
};
struct Wolf {
void woof(){ std::cout << "Woof!";}
};
int main() {
DisneyDuck q1, q2;
let_them_quack2(&q1, &q2);
RegularDuck q3, q4;
let_them_quack2(&q3, &q4);
//Wolf w1, w2;
//let_them_quack2(&w1, &w2); // ERROR: constraints not satisfied
}
output:
Quack!Quack!Quack2!Quack2!
As you can see, you will be able to: omit writing a template parameter list, ItQuacks is quite explicit so types are never used and that it's only the interface that matters takes place. This I'd like to have sort of an interface annotation/check. also takes place, concept use will also give you meaningfull error message.
We only need to write one version of the function:
#include <utility>
template<typename... Quackers>
void let_them_quack(Quackers&& ...quackers) {
using expand = int[];
void(expand { 0, (std::forward<Quackers>(quackers).quack(), 0)... });
}
struct Duck {
void quack() {}
};
int main()
{
Duck a, b, c;
let_them_quack(a, b, c, Duck());
}

Where do you find templates useful?

At my workplace, we tend to use iostream, string, vector, map, and the odd algorithm or two. We haven't actually found many situations where template techniques were a best solution to a problem.
What I am looking for here are ideas, and optionally sample code that shows how you used a template technique to create a new solution to a problem that you encountered in real life.
As a bribe, expect an up vote for your answer.
General info on templates:
Templates are useful anytime you need to use the same code but operating on different data types, where the types are known at compile time. And also when you have any kind of container object.
A very common usage is for just about every type of data structure. For example: Singly linked lists, doubly linked lists, trees, tries, hashtables, ...
Another very common usage is for sorting algorithms.
One of the main advantages of using templates is that you can remove code duplication. Code duplication is one of the biggest things you should avoid when programming.
You could implement a function Max as both a macro or a template, but the template implementation would be type safe and therefore better.
And now onto the cool stuff:
Also see template metaprogramming, which is a way of pre-evaluating code at compile-time rather than at run-time. Template metaprogramming has only immutable variables, and therefore its variables cannot change. Because of this template metaprogramming can be seen as a type of functional programming.
Check out this example of template metaprogramming from Wikipedia. It shows how templates can be used to execute code at compile time. Therefore at runtime you have a pre-calculated constant.
template <int N>
struct Factorial
{
enum { value = N * Factorial<N - 1>::value };
};
template <>
struct Factorial<0>
{
enum { value = 1 };
};
// Factorial<4>::value == 24
// Factorial<0>::value == 1
void foo()
{
int x = Factorial<4>::value; // == 24
int y = Factorial<0>::value; // == 1
}
I've used a lot of template code, mostly in Boost and the STL, but I've seldom had a need to write any.
One of the exceptions, a few years ago, was in a program that manipulated Windows PE-format EXE files. The company wanted to add 64-bit support, but the ExeFile class that I'd written to handle the files only worked with 32-bit ones. The code required to manipulate the 64-bit version was essentially identical, but it needed to use a different address type (64-bit instead of 32-bit), which caused two other data structures to be different as well.
Based on the STL's use of a single template to support both std::string and std::wstring, I decided to try making ExeFile a template, with the differing data structures and the address type as parameters. There were two places where I still had to use #ifdef WIN64 lines (slightly different processing requirements), but it wasn't really difficult to do. We've got full 32- and 64-bit support in that program now, and using the template means that every modification we've done since automatically applies to both versions.
One place that I do use templates to create my own code is to implement policy classes as described by Andrei Alexandrescu in Modern C++ Design. At present I'm working on a project that includes a set of classes that interact with BEA\h\h\h Oracle's Tuxedo TP monitor.
One facility that Tuxedo provides is transactional persistant queues, so I have a class TpQueue that interacts with the queue:
class TpQueue {
public:
void enqueue(...)
void dequeue(...)
...
}
However as the queue is transactional I need to decide what transaction behaviour I want; this could be done seperately outside of the TpQueue class but I think it's more explicit and less error prone if each TpQueue instance has its own policy on transactions. So I have a set of TransactionPolicy classes such as:
class OwnTransaction {
public:
begin(...) // Suspend any open transaction and start a new one
commit(..) // Commit my transaction and resume any suspended one
abort(...)
}
class SharedTransaction {
public:
begin(...) // Join the currently active transaction or start a new one if there isn't one
...
}
And the TpQueue class gets re-written as
template <typename TXNPOLICY = SharedTransaction>
class TpQueue : public TXNPOLICY {
...
}
So inside TpQueue I can call begin(), abort(), commit() as needed but can change the behaviour based on the way I declare the instance:
TpQueue<SharedTransaction> queue1 ;
TpQueue<OwnTransaction> queue2 ;
I used templates (with the help of Boost.Fusion) to achieve type-safe integers for a hypergraph library that I was developing. I have a (hyper)edge ID and a vertex ID both of which are integers. With templates, vertex and hyperedge IDs became different types and using one when the other was expected generated a compile-time error. Saved me a lot of headache that I'd otherwise have with run-time debugging.
Here's one example from a real project. I have getter functions like this:
bool getValue(wxString key, wxString& value);
bool getValue(wxString key, int& value);
bool getValue(wxString key, double& value);
bool getValue(wxString key, bool& value);
bool getValue(wxString key, StorageGranularity& value);
bool getValue(wxString key, std::vector<wxString>& value);
And then a variant with the 'default' value. It returns the value for key if it exists, or default value if it doesn't. Template saved me from having to create 6 new functions myself.
template <typename T>
T get(wxString key, const T& defaultValue)
{
T temp;
if (getValue(key, temp))
return temp;
else
return defaultValue;
}
Templates I regulary consume are a multitude of container classes, boost smart pointers, scopeguards, a few STL algorithms.
Scenarios in which I have written templates:
custom containers
memory management, implementing type safety and CTor/DTor invocation on top of void * allocators
common implementation for overloads wiht different types, e.g.
bool ContainsNan(float * , int)
bool ContainsNan(double *, int)
which both just call a (local, hidden) helper function
template <typename T>
bool ContainsNanT<T>(T * values, int len) { ... actual code goes here } ;
Specific algorithms that are independent of the type, as long as the type has certain properties, e.g. binary serialization.
template <typename T>
void BinStream::Serialize(T & value) { ... }
// to make a type serializable, you need to implement
void SerializeElement(BinStream & strean, Foo & element);
void DeserializeElement(BinStream & stream, Foo & element)
Unlike virtual functions, templates allow more optimizations to take place.
Generally, templates allow to implement one concept or algorithm for a multitude of types, and have the differences resolved already at compile time.
We use COM and accept a pointer to an object that can either implement another interface directly or via [IServiceProvider](http://msdn.microsoft.com/en-us/library/cc678965(VS.85).aspx) this prompted me to create this helper cast-like function.
// Get interface either via QueryInterface of via QueryService
template <class IFace>
CComPtr<IFace> GetIFace(IUnknown* unk)
{
CComQIPtr<IFace> ret = unk; // Try QueryInterface
if (ret == NULL) { // Fallback to QueryService
if(CComQIPtr<IServiceProvider> ser = unk)
ser->QueryService(__uuidof(IFace), __uuidof(IFace), (void**)&ret);
}
return ret;
}
I use templates to specify function object types. I often write code that takes a function object as an argument -- a function to integrate, a function to optimize, etc. -- and I find templates more convenient than inheritance. So my code receiving a function object -- such as an integrator or optimizer -- has a template parameter to specify the kind of function object it operates on.
The obvious reasons (like preventing code-duplication by operating on different data types) aside, there is this really cool pattern that's called policy based design. I have asked a question about policies vs strategies.
Now, what's so nifty about this feature. Consider you are writing an interface for others to use. You know that your interface will be used, because it is a module in its own domain. But you don't know yet how people are going to use it. Policy-based design strengthens your code for future reuse; it makes you independent of data types a particular implementation relies on. The code is just "slurped in". :-)
Traits are per se a wonderful idea. They can attach particular behaviour, data and typedata to a model. Traits allow complete parameterization of all of these three fields. And the best of it, it's a very good way to make code reusable.
I once saw the following code:
void doSomethingGeneric1(SomeClass * c, SomeClass & d)
{
// three lines of code
callFunctionGeneric1(c) ;
// three lines of code
}
repeated ten times:
void doSomethingGeneric2(SomeClass * c, SomeClass & d)
void doSomethingGeneric3(SomeClass * c, SomeClass & d)
void doSomethingGeneric4(SomeClass * c, SomeClass & d)
// Etc
Each function having the same 6 lines of code copy/pasted, and each time calling another function callFunctionGenericX with the same number suffix.
There were no way to refactor the whole thing altogether. So I kept the refactoring local.
I changed the code this way (from memory):
template<typename T>
void doSomethingGenericAnything(SomeClass * c, SomeClass & d, T t)
{
// three lines of code
t(c) ;
// three lines of code
}
And modified the existing code with:
void doSomethingGeneric1(SomeClass * c, SomeClass & d)
{
doSomethingGenericAnything(c, d, callFunctionGeneric1) ;
}
void doSomethingGeneric2(SomeClass * c, SomeClass & d)
{
doSomethingGenericAnything(c, d, callFunctionGeneric2) ;
}
Etc.
This is somewhat highjacking the template thing, but in the end, I guess it's better than play with typedefed function pointers or using macros.
I personally have used the Curiously Recurring Template Pattern as a means of enforcing some form of top-down design and bottom-up implementation. An example would be a specification for a generic handler where certain requirements on both form and interface are enforced on derived types at compile time. It looks something like this:
template <class Derived>
struct handler_base : Derived {
void pre_call() {
// do any universal pre_call handling here
static_cast<Derived *>(this)->pre_call();
};
void post_call(typename Derived::result_type & result) {
static_cast<Derived *>(this)->post_call(result);
// do any universal post_call handling here
};
typename Derived::result_type
operator() (typename Derived::arg_pack const & args) {
pre_call();
typename Derived::result_type temp = static_cast<Derived *>(this)->eval(args);
post_call(temp);
return temp;
};
};
Something like this can be used then to make sure your handlers derive from this template and enforce top-down design and then allow for bottom-up customization:
struct my_handler : handler_base<my_handler> {
typedef int result_type; // required to compile
typedef tuple<int, int> arg_pack; // required to compile
void pre_call(); // required to compile
void post_call(int &); // required to compile
int eval(arg_pack const &); // required to compile
};
This then allows you to have generic polymorphic functions that deal with only handler_base<> derived types:
template <class T, class Arg0, class Arg1>
typename T::result_type
invoke(handler_base<T> & handler, Arg0 const & arg0, Arg1 const & arg1) {
return handler(make_tuple(arg0, arg1));
};
It's already been mentioned that you can use templates as policy classes to do something. I use this a lot.
I also use them, with the help of property maps (see boost site for more information on this), in order to access data in a generic way. This gives the opportunity to change the way you store data, without ever having to change the way you retrieve it.

How to use boost::mpl to compose policies?

I have used something like the following to compose policies for my application:
The policy classes look like this:
struct Policy {
static void init();
static void cleanup();
//...
};
template <class CarT, class CdrT>
struct Cons {
static void init() {
CarT::init();
CdrT::init();
}
static void cleanup() {
CdrT::cleanup();
CarT::cleanup();
}
//...
};
To compose policies:
typedef Cons<Policy1, Cons<Policy2, Cons<Policy3, Policy4> > > MyPolicy;
To use MyPolicy:
init_with<MyPolicy>(...);
//...
cleanup_with<MyPolicy>(...);
where they'd call:
MyPolicy::init_options(); // calls Policy1 to 4's init in order
and
MyPolicy::cleanup(); // calls Policy1 to 4's cleanup in reverse order
Essentially, Cons constructs a type list here. It's pretty straight forward. However the typedef cons line is kinda ugly. It'll be ideal to have policy combiner that can do this:
typedef CombinePolicy<Policy1, Policy2, Policy3, Policy4> MyPolicy;
Since we can have arbitrary number of policies, the CombinePolicy would need variadic template support in C++0x, which is only available experimentally in cutting edge compilers. However, it seems that boost:mpl library solved/worked around the problem by using a bunch preprocessing tricks. I guess I could use something like:
typedef mpl::list<Policy, Policy2, Policy3, Policy4> Policies;
and then calls:
init_with<Policies>(...);
which would then use:
typedef iter_fold<Policies, begin<Policies>::type,
some_magic_lambda_expression>::type MyPolicy;
Obviously, I have a little trouble figuring out some_magic_lambda_expression here. I'm sure it's quite trivial for mpl experts here.
Thanks in advance.
Since no one answered the question satisfactorily, I spent sometime digging into the boost::mpl source. Man, it's not pretty with layers of macros and hundreds of lines of specialization classes. I now have more appreciation for the authors of the boost libraries to make meta programming easier and more portable for us. Hopefully C++0x will make library writers' life easier as well.
Anyway, the solution turns out to be simple and elegant.
First iter_fold is not what I want, as I couldn't figure out how to specify an iterator that can be deferenced to a null type. So I fiddled around with fold and find the following:
typedef fold<Policies, Null, Cons<_1, _2> >::type MyPolicy;
In order for this to work, I need to provide the Null type and a specialization for Cons:
struct Null { };
template<class PolicyT>
struct Cons<Null, PolicyT> {
static void init() { PolicyT::init(); }
static void cleanup() { PolicyT::cleanup(); }
};
I think your problem is rather runtime invocation than metafunctions, because you want to call the init functions on the actual runtime objects.
You could try the runtime algorithms of mpl,
like :
for_each<Policies>(InitPolicy());
with
struct InitPolicy() {
template<class Policy>
void operator() (Policy& p) { p.init_options(); }
};
I think you're looking for something like:
typedef
iter_fold<
Policies,
begin<Policies>::type,
Cons<_1,_2>
>::type
MyType;
You also might want to look into inherit_linearly<> if you buld-in some sort of CRTP to invoke a base's functions hard-wired at compile time.