How to handle template class static members and storage in situations where leaving to static cleanup isn't desired - c++

I've recently gotten back into C++ after many years in C# and java land, and am loving where C++ has gone in my absence (since pre C++11, am now soaking up C++20!). The power of templates is really exciting to me. However, I quickly ran into something that seems impossible to deal with.
I've written a template driven event system which am really happy with.
struct imgui_event_listener
{
void onCreatedWindow(events::ImGui_CreatedWindow f)
{
}
}
dispatcher::connect(&listener, &imgui_event_listener::onCreatedWindow);
...
dispatcher::fire(events::ImGui_CreatedWindow{ window });
I love it, it requires no template parameters, can use arbitary structs for events. There's one big snag though, and that is the near infinite and completely unknowable potential invisible versions of my event system, all using a few unordered_maps that need to go somewhere. They are currently static within methods.
Stuff like...
template <typename ListenerType, typename Type>
using FPtr = void(ListenerType::*)(Type);
template<typename ListenerType, typename Type>
using Tuple = eastl::tuple<ListenerType*, FPtr<ListenerType, Type>>;
template <typename ListenerType, typename Type>
using ListenerMap = eastl::unordered_map<uint32_t, Tuple<ListenerType, Type>>;
class EventSystem
{
template<typename ListenerType, typename Type>
ListenerMap<ListenerType, Type>& listenerMap()
{
static ListenerMap<ListenerType, Type> listenerMap;
return listenerMap;
}
}
I'm a relative noob these days so forgive if anything's weird.
This SEEMS to be too convenient and satisfying to be recommended, I expected people to be shouted down for some reason but it seems this is the way it's by necessity done most of the time.
But the game engine I'm working with has a memory manager, and doesn't use or recommend the STL, having its own replacement that's using the one open-sourced by EA for games, and has their own allocator that is to be used for it so it can track memory.
This tracks all memory usage and reports with an exception any leaks that occur at the time static objects are being removed.
Unfortunately despite the containers being static, the nodes of those unordered_maps are malloced from the memory managed heap. Expected usage would be to clear them on clean up which is what happens everywhere else.
Now, I suspect in actuality, these maps static instances will automatically be dealt with after the memory manager has already complained, however there's really no real way around avoiding it complain, even if only in debug, an exception on quit and seeing memory addresses reported as leaks is annoying, and it makes me feel ashamed when it does! It also could obscure real issues. I'm sure I could brute force normal STL maps with allocations, but I really want to follow the road laid out by the developers of the engine and avoid any future headaches. So its more about convenience and vanity than anything else but I need a way around this without sacrificing my event system's elegance of usage.
This lead me into the world of template meta-programming to try and collate all these template parameters into some mega tuple as the event connections are formed and the template instances are created at compile time, and looking into every conceivable pattern where I'd somehow be able to unwind all the template instances I've created to get at these in advance and be able to manually clean up, but it seems that template meta-programming requiring new 'variable names' for each instruction as typedefs or using means I can't iteratively do this from what I can see, but honestly the field is so complicated and light on relevant examples I don't know if I'm missing anything.
I've tried to think about where else these could be stored, but I just can't fathom how it'd be any different.
I could also just manually maintain a list of all my events, but then I'd lose one of its cooler and more flexible features.
OR somewhere else I can store them where I'd be able to access them. It seems like a catch-22 situation where their very existence demands they be in some inaccessible parallel universe..
So yeah, I know there are ways I could solve this without asking for help but they are all either sacrificing a feature of the system or potentially causing future issues. Not sure I've ever asked a question here, but this has really stumped me and I can't really find a similar issue from someone else, most are happy to use std library, have no memory manager, and putting static instances within functions is a super satisfyingly simple way to do it.
Thanks for your time! Forgive if a bit rambly but felt I needed to provide context. I know there's not really much code to show but you get my point I hope!

Something along these lines perhaps:
std::vector<std::function<void()>> cleanup_registry;
class EventSystem
{
template<typename ListenerType, typename Type>
ListenerMap<ListenerType, Type>& listenerMap()
{
static ListenerMap<ListenerType, Type> listenerMap;
static int dummy = (
cleanup_registry.push_back([&]() { listenerMap.clear(); }),
0);
return listenerMap;
}
};
void cleanup() {
for (auto& cleaner : cleanup_registry) {
cleaner();
}
std::vector<std::function<void()>>{}.swap(cleanup_registry);
}
Call cleanup() right before your game engine terminates.
You can use similar type-erasure techniques to eliminate ListenerType from your maps, having just one map per event type. Something like
template <typename Event>
using ListenerMap = eastl::unordered_map<uint32_t, std::function<void(Event)>>;
Then dispatcher::connect (where actual listener type is available) would manufacture a callback lambda to be placed into the map.

Related

Create an alias from one type to another

I'm writing some kind of DI container in c++ and I'm curious if it's possible to create aliases from one type to another in modern c++.
What I basicly want to do is to be able to call implementation constructor by it's aliased interface. Like so:
di::Register<Interface, Impl>();
di::Resolve<Interface>(); // -> Impl should be resolved
The problem is that I've not been able to find the way to alias Interface and Impl in compile time so far. I can do this using RTTI but I really don't want to use it. Is it possible at all?
By looking at the interface of your code, if you have a global state (which I don't actively recommend) you should get away with that:
using type_id_t = void(*)();
template<typename> void type_id() {}
struct di {
using create_function_t = void*(*)();
static std::unordered_map<type_id_t, create_function_t> types;
template<typename I, typename T>
static void Register() {
types.emplace(type_id<I>, []{
return static_cast<void*>(
static_cast<I*>(new T)
);
});
}
template<typename I>
static std::unique_ptr<I> Resolve() {
return std::unique_ptr<I>{static_cast<I*>(types[type_id<I>]())};
}
};
Live example
The problem is that I've not been able to find the way to alias Interface and Impl in compile time so far. I can do this using RTTI but I really don't want to use it. Is it possible at all?
There is a trick you can use to do this, assuming I understood your goal correctly. It won't look as nice as what you have there:
http://stackoverflow.com/questions/4790721/c-type-registration-at-compile-time-trick
This trick was attributed to Matt Calabrese, he described it in a Boostcon talk in like 2011.
To the best of my knowledge this trick is standards-conforming, but you must be very careful -- if you do start the registration in some header files and then continue it in some CPP files you may cause an ODR violation if you are careless.
I think you would end up with some macro like
REGISTER_PAIR( interface, impl );
and then you would have some type-alias, e.g.
get_registered_impl_t<interface>
which resolves to impl.
In the example they show how to make a list of types that is accumulated over time. In your case it would be a list of type-level "pairs" and you could search it by doing linear scan. You could try to use a fancy compile-time map data structure, but in most cases its pointless since linear scan will be fast enough, and also, the length of the list you can make is bounded by the maximum template instantiation depth of your compiler, which is typically like 100 or 200 or something. If you need larger lists there are some tricks you can use but I won't detail here.

Mechanism to shadow a void* pointer with a macro

I noticed that I can speed up compile times (significantly) by hiding complicated objects as void* pointers in my class, and dealing with them in a isolated cpp. Forward declaring these classes is too hard to maintain.
Using a macro sometimes works, but sometimes it doesn't. Does anybody know of a way to shadow a variable with a cast so that I can get l-value? Is there something I can do with a structure that has an implicit cast operator that can give me an l-value. Is there some paradigmatic way to handle these problems that I'm not seeing?
struct K : CGAL::Exact_predicates_inexact_constructions_kernel {};
typedef CGAL::Delaunay_triangulation_2<K> Triangulation;
typedef Triangulation::Vertex_handle Vertex_handle;
#define Triangulation_Ptr (static_cast<Triangulation*>(this->Triangulation_Ptr))
void MyClass::cleanTriangulation()
{
delete Triangulation_Ptr;//works, this->Triangulation_Ptr is a void*
}
void MyClass::addToTriangulation(int idx, MyPoint l)
{
if (Triangulation_Ptr == nullptr)
{
Triangulation_Ptr = new Triangulation;// No a l-value, doesn't compile
}
//something, that adds a point
}
You will get a lot of people suggesting you don't do this, but I share your pain. Quite apart from compile times, the careful design and use of a layer of typedefs, templates and even macros can produce code in which the business logic is far easier to understand, even if the underlying code is not. You leave yourself open to occasional weird compile errors, but in my view the effort is worth it in carefully chosen situations.
Having said that, what you are trying to is not necessarily easy to achieve. If you're going to use macros, you want to flag them in a way that those who use them know what they're playing with.
Does something like this work?
#define Triangulation_Ptr (Triangulation*)(&this->Triangulation_Ptr)
Part of the problem is that these are pointer-to-member, which are really not the same as ordinary pointers.

A C++ based variants chess engine design question

I have a chess variants engine that plays suicide chess and losers chess along with normal chess. I might, over time, add more variants to my engine. The engine is implemented completely in C++ with proper usage of OOP. My question is related to design of such a variant engine.
Initially the project started as a suicide-only engine while over time I added other flavors. For adding new variants, I experimented using polymorphism in C++ first. For instance, a MoveGenerator abstract class had two subclasses SuicideMoveGenerator and NormalMoveGenerator and depending on the type of game chosen by user, a factory would instantiate the right subclass. But I found this to be much slower - obviously because instantiating classes containing virtual functions and calling virtual functions in tight loops are both quite inefficient.
But then it occurred to me to use C++ templates with template specialization for separating logic for different variants with maximum reuse of code. This also seemed very logical because dynamic linking is not really necessary in the context as once you choose the type of game, you basically stick with it until the end of the game. C++ template specialization provides exactly this - static polymorphism. The template parameter is either SUICIDE or LOSERS or NORMAL.
enum GameType { LOSERS, NORMAL, SUICIDE };
So once user selects a game type, appropriate game object is instantiated and everything called from there will be appropriately templatized. For instance if user selects suicide chess, lets say:
ComputerPlayer<SUICIDE>
object is instantiated and that instantiation basically is linked to the whole control flow statically. Functions in ComputerPlayer<SUICIDE> would work with MoveGenerator<SUICIDE>, Board<SUICIDE> and so on while corresponding NORMAL one will appropriately work.
On a whole, this lets me instantiate the right templatize specialized class at the beginning and without any other if conditions anywhere, the whole thing works perfectly. The best thing is there is no performance penalty at all!
The main downside with this approach however is that using templates makes your code a bit harder to read. Also template specialization if not appropriately handled can lead to major bugs.
I wonder what do other variant engine authors normally do for separation of logic (with good reuse of code)?? I found C++ template programming quite suitable but if there's anything better out there, I would be glad to embrace. In particular, I checked Fairymax engine by Dr. H G Muller but that uses config files for defining game rules. I don't want to do that because many of my variants have different extensions and by making it generic to the level of config-files the engine might not grow strong. Another popular engine Sjeng is littered with if conditions everywhere and I personally feel thats not a good design.
Any new design insights would be very useful.
"Calling virtual functions in tight loops are inefficient"
I would be pretty surprised actually if this caused any real bloat, if all the variables of the loop have the same dynamic type, then I would expect the compiler to fetch the corresponding instruction from its L1 cache and thus not suffer much.
However there is one part that worries me:
"obviously because instantiating classes containing virtual functions [is] quite inefficient"
Now... I am really surprised.
The cost of instantiating a class with virtual functions is near undistinguishable from the cost of instantiating a class without any virtual functions: it's one more pointer, and that's all (on popular compilers, which corresponds to the _vptr).
I surmise that your problem lies elsewhere. So I am going to take a wild guess:
do you, by any chance, have a lot of dynamic instantiation going on ? (calling new)
If that is the case, you would gain much by removing them.
There is a Design Pattern called Strategy which would be eminently suitable for your precise situation. The idea of this pattern is akin, in fact, to the use of virtual functions, but it actually externalize those functions.
Here is a simple example:
class StrategyInterface
{
public:
Move GenerateMove(Player const& player) const;
private:
virtual Move GenerateMoveImpl(Player const& player) const = 0;
};
class SuicideChessStrategy: public StrategyInterface
{
virtual Move GenerateMoveImpl(Player const& player) const = 0;
};
// Others
Once implemented, you need a function to get the right strategy:
StrategyInterface& GetStrategy(GameType gt)
{
static std::array<StrategyInterface*,3> strategies
= { new SuicideChessStrategy(), .... };
return *(strategies[gt]);
}
And finally, you can delegate the work without using inheritance for the other structures:
class Player
{
public:
Move GenerateMove() const { return GetStrategy(gt).GenerateMove(*this); }
private:
GameType gt;
};
The cost is pretty much similar to using virtual functions, however you do not need dynamically allocated memory for the basic objects of your game any longer, and stack allocation is a LOT faster.
I'm not quite sure if this is a fit but you may be able to achieve static polymorphism via the CRTP with some slight modifications to your original design.

Dynamic C++

I'm wondering about an idea in my head. I want to ask if you know of any library or article related to this. Or you can just tell me this is a dumb idea and why.
I have a class, and I want to dynamically add methods/properties to it at runtime. I'm well aware of the techniques of using composite/command design pattern and using embedded scripting language to accomplish what I'm talking about. I'm just exploring the idea. Not necessary saying that it is a good idea.
class Dynamic
{
public:
typedef std::map<std::string, boost::function<void (Dynamic&)> > FuncMap;
void addMethod(const std::string& name, boost::function<void (Dynamic&)> func) {
funcMap_[name] = func;
}
void operator[](const std::string& name) {
FuncMap::iterator funcItr = funcMap_.find(name);
if (funcItr != funcMap_.end()) {
funcItr->second(*this);
}
}
private:
FuncMap funcMap_;
};
void f(Dynamic& self) {
doStuffWithDynamic(self);
}
int main()
{
Dynamic dyn;
dyn.addMethod("f", boost::bind(&f, _1));
dyn["f"]; // invoke f
}
The idea is that I can rebind the name "f" to any function at runtime. I'm aware of the performance problem in string lookup and boost::function vs. raw function pointer. With some hard work and non-portable hack I think I can make the performance problem less painful.
With the same kind of technique, I can do "runtime inheritance" by having a "v-table" for name lookup and dispatch function calls base on dynamic runtime properties.
If just want to tell me to use smalltalk or Objective-C, I can respect that but I love my C++ and I'm sticking with it.
What you want is to change C++ into something very different. One of the (many) goals of C++ was efficient implementation. Doing string lookup for function calls (no matter how well you implement it), just isn't going to be very efficient compared to the normal call mechanisms.
Basically, I think you're trying to shoehorn in functionality of a different language. You CAN make it work, to some degree, but you're creating C++ code that no one else is going to be able (or willing) to try to understand.
If you really want to write in a language that can change it's objects on the fly, then go find such a language (there are many choices, I'm sure). Trying to shoehorn that functionality into C++ is just going to cause you problems down the road.
Please note that I'm no stranger to bringing in non-C++ concepts into C++. I once spent a considerable amount of time removing another engineer's attempt at bringing a based-object system into a C++ project (he liked the idea of containers of 'Object *', so he made every class in the system descend from his very own 'Object' class).
Bringing in foreign language concepts almost always ends badly in two ways: The concept runs up against other C++ concepts, and can't work as well as it did in the source language, AND the concept tends to break something else in C++. You end up losing a lot of time trying to implement something that just isn't going to work out.
The only way I could see something like this working at all well, is if you implemented a new language on top of C++, with a cfront-style pre-compiler. That way, you could put some decent syntax onto the thing, and eliminate some of your problems.
If you implemented this, even as a pure library, and then used it extensively, you would in a way be using a new language - one with a hideous syntax, and a curious combination of runtime method resolution and unreliable bounds checking.
As a fan of C/C++ style syntax and apparently a fan of dynamic method dispatch, you may be interested in C# 4.0, which is now in Beta, and has the dynamic keyword to allow exactly this kind of thing to be seamlessly mixed into normal statically typed code.
I don't think it would be a good idea to change C++ enough to make this work. I'd suggest working in another language, such as Lisp or Perl or another language that's basically dynamic, or imbedding a dynamic language and using it.
What you are doing is actually a variation of the Visitor pattern.
EDIT: By the way, another approach would be by using Lua, since the language allows you to add functions at runtime. So does Objective-C++.
EDIT 2: You could actually inherit from FuncMap as well:
class Dynamic;
typedef std::map<std::string, boost::function<void (Dynamic&)> > FuncMap;
class Dynamic : public FuncMap
{
public:
};
void f(Dynamic& self) {
//doStuffWithDynamic(self);
}
int main()
{
Dynamic dyn;
dyn["f"] = boost::bind(&f, _1);
dyn["f"](dyn); // invoke f, however, 'dyn'param is awkward...
return 0;
}
If I understand what you are trying to accomplish correctly, it seems as though dynamic linking (i.e. Dynamically loaded libraries in windows or linux) will do most of what you are trying to accomplish.
That is, you can, at runtime, select the name of the function you want to execute (eg. the name of the DLL), which then gets loaded and executed. Much in the way that COM works. Or you can even use the name of the function exported from that library to select the correct function (C++ name mangling issues aside).
I don't think there's a library for this exact thing.
Of course, you have to have these functions pre-written somehow, so it seems there would be an easier way to do what you want. For example you could have just one method to execute arbitrary code from your favorite scripting language. That seems like an easier way to do what you want.
I keep thinking of the Visitor pattern. That allows you to do a vtable lookup on the visiting object (as well as the visited object, thought that doesn't seem relevant to your question).
And at runtime, you could have some variable which refers to the visitor, and call
Dynamic dynamic;
DynamicVisitor * dv = ...;
dynamic->Accept(dv);
dv = ...; // something else
dynamic->Accept(dv);
The point is, the visitor object has a vtable, which you said you wanted, and you can change its value dynamically, which you said you wanted. Accept is basically the "function to call things I didn't know about at compile time."
I've considered doing this before as well. Basically, however, you'd be on your way to writing a simple VM or interpreter (look at, say, Lua or Topaz's source to see what I mean -- Topaz is a dead project that pre-dates Parrot).
But if you're going that route it makes sense to just use an existing VM or interpreter.

Does anyone use template metaprogramming in real life? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I discovered template metaprogramming more than 5 years ago and got a huge kick out of reading Modern C++ Design but I never found an opertunity to use it in real life.
Have you ever used this technique in real code?
Contributors to Boost need not apply ;o)
I once used template metaprogramming in C++ to implement a technique called "symbolic perturbation" for dealing with degenerate input in geometric algorithms. By representing arithmetic expressions as nested templates (i.e. basically by writing out the parse trees by hand) I was able to hand off all the expression analysis to the template processor.
Doing this kind of thing with templates is more efficient than, say, writing expression trees using objects and doing the analysis at runtime. It's faster because the modified (perturbed) expression tree is then available to the optimizer at the same level as the rest of your code, so you get the full benefits of optimization, both within your expressions but also (where possible) between your expressions and the surrounding code.
Of course you could accomplish the same thing by implementing a small DSL (domain specific language) for your expressions and the pasting the translated C++ code into your regular program. That would get you all the same optimization benefits and also be more legible -- but the tradeoff is that you have to maintain a parser.
I've found policies, described in Modern C++ Design, really useful in two situations:
When I'm developing a component that I expect will be reused, but in a slightly different way. Alexandrescu's suggestion of using a policy to reflect a design fits in really well here - it helps me get past questions like, "I could do this with a background thread, but what if someone later on wants to do it in time slices?" Ok fine, I just write my class to accept a ConcurrencyPolicy and implement the one I need at the moment. Then at least I know the person who comes behind me can write and plug in a new policy when they need it, without having to totally rework my design. Caveat: I have to reign myself in sometimes or this can get out of control -- remember the YAGNI principle!
When I'm trying to refactor several similar blocks of code into one. Usually the code will be copy-pasted and modified slightly because it would have had too much if/else logic otherwise, or because the types involved were too different. I've found that policies often allow for a clean one-fits-all version where traditional logic or multiple inheritance would not.
I've used it in the inner loops of a game's graphics code, where you want some level of abstraction and modularity but can't pay the cost of branches or virtual calls. Overall it was a better solution than a proliferation of handwritten special-case functions.
Template metaprogramming and expression templates are becoming more popular in the scientific community as optimization methods that offload some of the computational effort onto the compiler while maintaining some abstraction. The resulting code is larger and less readable, but I have used these techniques to speed up linear algebra libraries and quadrature methods in FEM libraries.
For application-specific reading, Todd Veldhuizen is a big name in this area. A popular book is C++ and Object Oriented Numeric Computing for Scientists and Engineers by Daoqi Yang.
Template meta programming is a wonderful and power technique when writing c++ libraries. I've used it a few time in custom solutions, but usually a less elegant old style c++ solution is easier to get through code review and easier to maintain for other users.
However, I've got a lot of mileage out of template meta programming when writing reusable components/libraries. I'm not talking anything as large some of Boost's stuff just smallish components that will be reused frequently.
I used TMP for a singleton system where the user could specify what type of singleton they desired. The interface was very basic. Underneath it was powered by heavy TMP.
template< typename T >
T& singleton();
template< typename T >
T& zombie_singleton();
template< typename T >
T& phoenix_singleton();
Another successful use was simplifying our IPC layer. It is built using classic OO style. Each message needs to derive from an abstract base class and override some serialization methods. Nothing too extreme, but it generates a lot of boiler plate code.
We threw some TMP at it and automated the generation of all the code for the simple case of messages containing only POD data. The TMP messages still used the OO backend but they massively reduce the amount of boiler plate code. The TMP was also used to generate the message vistor. Over time all our message migrated to the TMP method. It was easier and less code to build a simple POD struct just for message passing and add the few (maybe 3) lines needed to get the TMP to generate the classes than it was to derive a new message to send a regular class across the IPC framework.
I use template metaprogramming all the time, but in D, not C++. C++'s template metalanguage was originally designed for simple type parametrization and became a Turing complete metalanguage almost by accident. It is therefore a Turing tarpit that only Andrei Alexandrescu, not mere mortals, can use.
D's template sublanguage, on the other hand, was actually designed for metaprogramming beyond simple type parameterization. Andrei Alexandrescu seems to love it, but other people can actually understand his D templates. It's also powerful enough that someone wrote a compile-time raytracer in it as a proof of concept.
I guess the most useful/non-trivial metaprogram I ever wrote in D was a function template that, given a struct type as the template parameter and a list of column header names in an order corresponding to the variable declarations in the struct as a runtime parameter, will read in a CSV file, and return an array of structs, one for each row, with each struct field corresponding to a column. All type conversions (string to float, int, etc.) are done automatically, based on the types of the template fields.
Another good one, which mostly works, but still doesn't handle a few cases properly, is a deep copy function template that handles structs, classes, and arrays properly. It uses only compile time reflection/introspection, so that it can work with structs, which, unlike full-blown classes, have no runtime reflection/introspection capabilities in D because they're supposed to be lightweight.
Most programmers who use template metaprogramming use it indirectly, through libraries like boost. They don't even probably know what is happening behind the scenes, only that it makes the syntax of certain operations much much easier.
I've used it quite a bit with DSP code, especially FFTs, fixed size circular buffers, hadamard transforms and the like.
For those familiar with Oracle Template Library (OTL), boost::any and Loki library (the one described in Modern C++ Design) here's the proof of concept TMP code that enables you to store one row of otl_stream in vector<boost::any> container and access data by column number. And 'Yes', I'm going to incorporate it in production code.
#include <iostream>
#include <vector>
#include <string>
#include <Loki/Typelist.h>
#include <Loki/TypeTraits.h>
#include <Loki/TypeManip.h>
#include <boost/any.hpp>
#define OTL_ORA10G_R2
#define OTL_ORA_UTF8
#include <otlv4.h>
using namespace Loki;
/* Auxiliary structs */
template <int T1, int T2>
struct IsIntTemplateEqualsTo{
static const int value = ( T1 == T2 );
};
template <int T1>
struct ZeroIntTemplateWorkaround{
static const int value = ( 0 == T1? 1 : T1 );
};
/* Wrapper class for data row */
template <class TList>
class T_DataRow;
template <>
class T_DataRow<NullType>{
protected:
std::vector<boost::any> _data;
public:
void Populate( otl_stream& ){};
};
/* Note the inheritance trick that enables to traverse Typelist */
template <class T, class U>
class T_DataRow< Typelist<T, U> >:public T_DataRow<U>{
public:
void Populate( otl_stream& aInputStream ){
T value;
aInputStream >> value;
boost::any anyValue = value;
_data.push_back( anyValue );
T_DataRow<U>::Populate( aInputStream );
}
template <int TIdx>
/* return type */
Select<
IsIntTemplateEqualsTo<TIdx, 0>::value,
typename T,
typename TL::TypeAt<
U,
ZeroIntTemplateWorkaround<TIdx>::value - 1
>::Result
>::Result
/* sig */
GetValue(){
/* body */
return boost::any_cast<
Select<
IsIntTemplateEqualsTo<TIdx, 0>::value,
typename T,
typename TL::TypeAt<
U,
ZeroIntTemplateWorkaround<TIdx>::value - 1
>::Result
>::Result
>( _data[ TIdx ] );
}
};
int main(int argc, char* argv[])
{
db.rlogon( "AMONRAWMS/WMS#amohpadb.world" ); // connect to Oracle
std::cout<<"Connected to oracle DB"<<std::endl;
otl_stream o( 1, "select * from blockstatuslist", db );
T_DataRow< TYPELIST_3( int, int, std::string )> c;
c.Populate( o );
typedef enum{ rcnum, id, name } e_fields;
/* After declaring enum you can actually acess columns by name */
std::cout << c.GetValue<rcnum>() << std::endl;
std::cout << c.GetValue<id>() << std::endl;
std::cout << c.GetValue<name>() << std::endl;
return 0;
};
For those not familiar with mentioned libraries.
The problem with OTL's otl_stream container is that one can access columns data only in sequential order by declaring variables of appropriate type and applying the operator >> to otl_stream object in the following way:
otl_stream o( 1, "select * from blockstatuslist", db );
int rcnum;
int id;
std::string name;
o >> rcnum >> id >> name;
It's not always convenient. The workaround is to write some wrapper class and to populate it with data from otl_stream. The desire is to be able to declare the list of column types and then:
take the type T of the column
declare variable of that type
apply olt_stream::operator >>(T&)
store the result (in the vector of boost::any)
take the type of the next column and repeat until all columns are processed
You can do all this with the help of Loki's Typelist struct, template specialization and inheritance.
With the help of Loki's library constructs you can also generate bunch of GetValue functions that return values of appropriate type deducing it from column's number (actually number of type in Typelist).
Almost 8 months after asking this I've finally used some TMP, I use a TypeList of interfaces in order to implement QueryInterface in a base class.
I use it with boost::statechart for large statemachines.
Yes I have, mostly to do some things that resemble duck-typing when I was wrapping a legacy API in a more modern C++ interface.
No I haven't used it in production code.
Why?
We have to support 6+ platforms with native platform compilers. It's
hard enough to use STL in this environment let alone modern template
techniques.
Developers don't seem to be keeping up C++ advances anymore. We use C++
when we have to. We have legacy code with legacy designs. New code is
done in something else e.g., Java, Javascript, Flash.
Don't do that. The reason behind that is as follows: by nature of template metaprogramming, if some part of your logic is done at compile-time, every logic that it is dependent on must be done at compile time as well. Once you start it, do one portion of your logic at compile time, there is no return. The snowball will keep on rolling and there is no way to stop it.
For example, you can't iterate on the elements of a boost::tuple<>, because you can only access them at compile time. You must use template metaprogramming to achieve what would have been easy and straightforward C++, and this always happens when the users of C++ aren't careful enough not to move too many things to compile-time. Sometimes it is difficult to see when a certain use of compiletime logic would become problematic, and sometimes programmers are eager to try and test what they've read in Alexandrescu's. In any case, this is a very bad idea in my opinion.
Many programmers don't use templates much because of the poor compiler support up until recently. However, while templates have had a lot of issues in the pas, newer compilers have much better support. I write code that has to work with GCC on Mac and Linux as well as Microsoft Visual C++ and it's only with GCC 4 and VC++ 2005 that these compiler have supported the standard really well.
Generic programming via templates is not something you need all the time but is definitely a useful code to have in your toolbox.
The obvious example container classes but templates are also useful for many other things. Two examples from my own work are:
Smart pointers ( e.g. Reference-counted, copy-on-write, etc.)
Math support classes such as Matrices, vectors, splines, etc. that need to support a variety of data types and still be efficient.