Generic Messaging when concrete Messages are autogenerated C++ classes from XML - c++

Background
I have auto generated concrete message types from a XML -> C++ generator.
GenMsg1, GenMsg2, ... , GenMsgN
All of these generated classes are from an XML schema. Technically I can edit their cpp and hpp files but I would prefer to not touch these as much as possible. They all have guaranteed functions that I would like to be able to call generically.
NOTE: I cannot get away from the above situation as this is a design limitation from another project. Also, I just used raw pointers in this simple example. I understand this is not best practice, its just for showing a general idea.
Goal
I am looking to process the above generated messages generically on my side.
Idea 1 and 2
My first idea was to just create and general "Message" class that was templated to hold one of the above types with a simple enum for identifying what type of message it is. The problem with this is I cannot just pass around a pointer to Message because it needs the template type parameter so this is obviously a no-go.
My next thought was to use the Curiously Recurring Template Pattern but that has the same issues as above.
Idea 3
After a lot of reading on messaging frameworks my next thought was that std::variant might be an option.
I have the following example which works but it uses double pointers and templated functions to access. If the wrong datatype is used this will throw an exception at runtime (which makes it quite clear this is the issue) but I could see this being annoying down the line as far as tracking the source of the throw.
I keep trying to read up on the std::visit but it does not make a whole lot of sense to me. I do not really want to implement a separate visitor class with a bunch of functions by hand when all of the functions in the generated classes are autogenerated already(like foo in the example below) and are ready to be called when the type is known. Additionally, they are guaranteed to exist. So it would be kind of nice to be able to call a foo() in Message and have it dive into the internal Representation and call its foo.
I have a MsgType enum in there that I could use as well. When the internal representation is set, I could set that and use it for deducing type... But this seems like its just duplicating effort already done by the std::variant so I scrapped its use but kept it in the code blow in case someone here had a new idea where something like that could be useful.
Any ideas on design moving forward? This seems like the most promising route, but I am open to ideas. Also, with my reality of having to conform to other peoples design decisions I realize that this code will "smell" a bit no matter what. I am just trying to make it as clean as possible on my end.
Idea 3 Code
#include <iostream>
#include <variant>
enum class MsgType { NOTYPE = 0, GenMessage1 = 1, GenMessage2 = 2, GenMessage3 = 3 };
class GenMessage1
{
public:
void foo() {std::cout << "Msg 1" << std::endl;}
};
class GenMessage2
{
public:
void foo() { std::cout << "Msg 2" << std::endl; }
};
class GenMessage3
{
public:
void foo() { std::cout << "Msg 3" << std::endl; }
};
class Message
{
private:
MsgType msgType;
std::string xmlStrRep;
std::variant<GenMessage1*, GenMessage2*, GenMessage3*> internalRep;
public:
Message()
{
this->msgType = MsgType::NOTYPE;
this->xmlStrRep = "";
}
template <typename T>
void setInternalRep(T* internalRep)
{
this->internalRep = internalRep;
}
template <typename T>
void getInternalRep(T retrieved)
{
*retrieved = getInternalRepHelper(*retrieved);
}
template <typename T>
T getInternalRepHelper(T retrieved)
{
return std::get<T>(this->internalRep);
}
void foo()
{
//call into interal representation and call its foo
}
};
int main()
{
Message* msg = new Message();
GenMessage3* incomingMsg = new GenMessage3();
GenMessage3* retrievedMsg;
msg->setInternalRep(incomingMsg);
msg->getInternalRep(&retrievedMsg);
retrievedMsg->foo();
return 0;
}
Outputs:
Msg 3

I think std::visit is, as you suspected, what you need. You can implement your foo() function like this:
void foo()
{
std::visit([](auto* message) {message->foo();}, this->internalRep);
}
Using a generic lambda (taking auto), it can be thought of as a template function, where the lambda's argument message is the actual type of the message in the variant, and you can use it directly. Provided all the messages have the same interface that you want to use, then you can do this with all the interface functions.

Related

how can I wrap libraries with templated code which requires runtime dispatch and/or inheritence

Motivation: In a suite of software, we make use of multiple unix-philosophied binaries that accomplish various tasks. These binaries will load configuration files of various types (yaml, json, xml, ini) and it's come to the point that we need to wrap these various features up into a tidy wrapper. All of the libraries (simdjson, yamlcpp, rapidxml) come with fairly modern C++ interfaces, but they are all slightly different from each other.
For instance, while yamlcpp checks the existence of a key simply by casting a node to bool, in simdjson you need to get the element and compare its .error() value to field not found constant.
All of the above means that subtle bugs are becoming more and more common because of slightly different handling methods, and it is a burden to ask the developer to be weary of each library's idiosyncracy. Also, some libraries load either json or yaml files, and this means that there are two code paths to load the same functional configuration.
Of particular note is that casting is different in each library and the exceptions raised (sometimes none) are not uniform.
(Since this is a one-time startup configuration problem, speed is not a major concern.)
Solution: the solution in principle is quite simple. I'd like to create an extremely thin templated wrapper around the libraries.
The problem I'm running into, however, is that the configuration file is fed through at run-time, and so this can't simply be a templated compile-time solution.
The Question: having presented the motivation and attempt at solution, here's my problem
Consider the following minimal code:
#include <iostream>
class simdjson {};
class YAML {}; // for compilability of example
struct Node
{
operator int() const { return 123; }
};
template<typename T> struct NodeImpl : public Node
{
operator int() const;
/* ... a bunch of common code ... */
};
/* ... tiny bits of specialization ... */
template<> NodeImpl<YAML>::operator int() const {return 42; /* return node.asInt(); */ }
template<> NodeImpl<simdjson>::operator int() const {return 52; /* return node.as<int>(); */}
int main() {
Node no_worky = NodeImpl<YAML>();
NodeImpl<YAML> a = NodeImpl<YAML>();
std::cout << "expect 42, got: " << (int)a << std::endl
<< "expect 42, got: " << (int)no_worky;
return 0;
}
There are 2 problems:
the fact that the type of configuration format can be determined at runtime requires this to be something other than a strictly templated solution (hence the inheritence)
making it inheritence based means that I (think) I have no solution other than virtual pointers and a virtual base Node class. This saddens me that I can't pass around the nodes by value (which I normally would be able to do in a purely templated implementation).
Is there an elegant solution I'm missing here, or is it simply that the runtime constraint means that I am constrained to use virtual base classes.
Edit after quite a bit of mucking around, I've come to the conclusion that this should be implemented entirely statically, and that the configuration code should be an unspecialized templated call like so:
template<typename K> void configure(NodeImpl<K> root)
{
std::cout << "expect 42, got: " << (int)root << std::endl;
/* ... do configuration stuff ... */
}
int main() {
if( /* file is yaml */ )
configure(NodeImpl<YAML>());
else if (/* file is json */)
configure(NodeImpl<json>());
return 0;
}
At first this felt like code duplication until I realized that one way or another, 2 branches of code will be emitted - whether I hide that behind a virtualization or not.
The above approach is entirely templated, and is entirely more sane.

macro that defines entire derived class from one function and certain type specifiers?

I have a class called system. A system takes some object managers and changes all objects in them in some way.
For example there might be a system that draws all images in a imageManager.
Every derived class works somewhat like this (pseudo code):
class someChildClass : public System{
private:
someObjectManager &mang1; //these are used by the update method.
someOtherObjectManager &mang2;//the update method changes these somehow
public:
someChildClass(someObjectManager &mang1, someObjectManager &mang2)
:mang1(mang1),mang2(mang2){
}
virtual void update(){
//this is pure virtual in the System base class.
//Do something with the managers here
}
}
I feel like writing everything but the update method is a waste of time and a source of errors. I wanted to write a macro that basically makes a class like this like so:
QUICKSYSTEM(thisIsTheSystemName, someObjectManager, mang1, someOtherObjectManager, mang2, ... (infinite possible Managers. So a variadic macro?)){
//this is the update function
}
}//this is the end braked for the class declaration. Its ugly but I dont know how I could do the function differently?
well I am having some problems making the macro. Everything works fine until I need to split the variadic arguments into the names and the types. I dont know if this is even possible now, since I cant go back and forth in the arguments easily or apply a easy step to them to make sure that every 2nd is the name of the variable. I would be ok with omitting the possibility for names and just had the types with some sort of automatic naming (manager1,manager2,manager3 or something like that).
If this isnt possible using a macro, what would be a better way to avoid mistakes and cut some time in the constructor and class declaration part?
Yeah, macros are really, really not the way to do this. C++ has templates, which follow C++ syntax and support C++ expressions. Macros instead use their own preprocessor language, which is almost entirely unaware of C++.
You'll want to read up a bit on std::tuple as well. It's going to be rather tricky to handle all those managers with those names. Tuples are the Standard solution for that. managers.get<0> and managers.get<someObjectManager> both work.
Variadic templates are the tool you need here:
#include <iostream>
#include <tuple>
#include <functional>
struct System { void virtual update() = 0; };
template<class... Managers>
struct ManagedSystem : System
{
std::function<void(Managers&...)> _update;
std::tuple<Managers&...> _managers;
template<class F>
ManagedSystem(F update, Managers&... managers) : _update(update), _managers(managers...) {}
void update() override { _update(std::get<Managers&>(_managers)...); }
};
int main()
{
int n = 0;
double d = 3.14;
auto reset = [](int& a, double& d) { a = 0; d = 0.0; };
ManagedSystem<int, double> ms{reset, n, d};
ms.update();
std::cout << "n = " << n << ", d = " << d << "\n";
// n = 0, d = 0
}
The idea is to define a templated-class (ManagedSystem) taking as template-parameters multiple manager types. This class inherits from Systemand provides a constructor taking:
an update functor,
and references to manager whose type is defined by the template parameters of the class.
The said managers are registered internally in an std::tuple and (with a bit of parameter pack magic fed to the update functor.
From there, you can define an inherited class from System by providing an update function and a type list. This avoids the use of ugly and type-unsafe macros in favor of the not-less ugly but type-string templates ;)

Calling different template function specialisations based on a run-time value

This is related to a previous question in that it's part of the same system, but it's a different problem.
I'm working on an in-house messaging system, which is designed to send messages (structs) to consumers.
When a project wants to use the messaging system, it will define a set of messages (enum class), the data types (struct), and the relationship between these entities:
template <MessageType E> struct expected_type;
template <> struct expected_type<MessageType::TypeA> { using type = Foo; };
template <> struct expected_type<MessageType::TypeB> { using type = Bar; };
template <> struct expected_type<MessageType::TypeM> { using type = Foo; };
Note that different types of message may use the same data type.
The code for sending these messages is discussed in my previous question. There's a single templated method that can send any message, and maintains type safety using the template definitions above. It works quite nicely.
My question regards the message receiver class. There is a base class, which implements methods like these:
ReceiveMessageTypeA(const Foo & data) { /* Some default action */ };
ReceiveMessageTypeB(const Bar & data) { /* Some default action */ };
ReceiveMessageTypeM(const Foo & data) { /* Some default action */ };
It then implements a single message processing function, like this:
bool ProcessMessage(MessageType msgType, void * data) {
switch (msgType) {
case TypeA:
ReceiveMessageTypeA(data);
break;
case TypeB:
ReceiveMessageTypeB(data);
break;
// Repeat for all supported message types
default:
// error handling
break;
}
}
When a message receiver is required, this base class is extended, and the desired ReceiveMessageTypeX methods are implemented. If that particular receiver doesn't care about a message type, the corresponding function is left unimplemented, and the default from the base class is used instead.
Side note: ignore the fact that I'm passing a void * rather than the specific type. There's some more code in between to handle all that, but it's not a relevant detail.
The problem with the approach is the addition of a new message type. As well as having to define the enum, struct, and expected_type<> specialisation, the base class has to be modified to add a new ReceiveMessageTypeX default method, and the switch statement in the ProcessMessage function must be updated.
I'd like to avoid manually modifying the base class. Specifically, I'd like to use the information stored in expected_type to do the heavy lifting, and to avoid repetition.
Here's my attempted solution:
In the base class, define a method:
template <MessageType msgType>
bool Receive(expected_type<msgType>::type data) {
// Default implementation. Print "Message not supported", or something
}
Then, the subclasses can just implement the specialisations they care about:
template<> Receive<MessageType::TypeA>(const Foo & data) { /* Some processing */ }
// Don't care about TypeB
template<> Receive<MessageType::TypeM>(const Foo & data) { /* Some processing */ }
I think that solves part of the problem; I don't need to define new methods in the base class.
But I can't figure out how to get rid of the switch statement. I'd like to be able to do this:
bool ProcessMessage(MessageType msgType, void * data) {
Receive<msgType>(data);
}
This won't do, of course, because templates don't work like that.
Things I've thought of:
Generating the switch statement from the expected_type structure. I have no idea how to do this.
Maintaining some sort of map of function pointers, and calling the desired one. The problem is that I don't know how to initialise the map without repeating the data from expected_type, which I don't want to do.
Defining expected_type using a macro, and then playing preprocessor games to massage that data into a switch statement as well. This may be viable, but I try to avoid macros if possible.
So, in summary, I'd like to be able to call a different template specialisation based on a run-time value. This seems like a contradiction to me, but I'm hoping someone can point me in a useful direction. Even if that is informing me that this is not a good idea.
I can change expected_type if needed, as long as it doesn't break my Send method (see my other question).
You had right idea with expected_type and Receive templates; there's just one step left to get it all working.
First, we need to give us some means to enumerate over MessageType:
enum class MessageType {
_FIRST = 0,
TypeA = _FIRST,
TypeB,
TypeM = 100,
_LAST
};
And then we can enumerate over MessageType at compile time and generate dispatch functions (using SFINAE to skip values not defined in expected_types):
// this overload works when expected_types has a specialization for this value of E
template<MessageType E> void processMessageHelper(MessageType msgType, void * data, typename expected_type<E>::type*) {
if (msgType == E) Receive<E>(*(expected_type<E>::type*)data);
else processMessageHelper<(MessageType)((int)E + 1)>(msgType, data, nullptr);
}
template<MessageType E> void processMessageHelper(MessageType msgType, void * data, bool) {
processMessageHelper<(MessageType)((int)E + 1)>(msgType, data, nullptr);
}
template<> void processMessageHelper<MessageType::_LAST>(MessageType msgType, void * data, bool) {
std::cout << "Unexpected message type\n";
}
void ProcessMessage(MessageType msgType, void * data) {
processMessageHelper<MessageType::_FIRST>(msgType, data, nullptr);
}
Your title says: "Calling different template function specialisations based on a run-time value"
That can only be done with some sort of manual switch statement, or with virtual functions.
On the one hand, it looks on the surface like you are doing object-oriented programming, but you don't yet have any virtual methods. If you find you are writing pseudo-objects everywhere, but you don't have any virtual functions, then it means you are not doing OOP. This is not a bad thing though. If you overuse OOP, then you might fail to appreciate the particular cases where it is useful and therefore it will just cause more confusion.
Simplify your code, and don't get distracted by OOP
You want the message type object to have some 'magic' associated with it, where it's MessageType controls how it is dispatched. This means you need a virtual function.
struct message {
virtual void Receive() = 0;
}
struct message_type_A : public message {
virtual void Receive() {
....
}
}
This allows you, where appropriate, to pass these objects as message&, and to call msg.process_me()

Use templates to clone class types exactly?

I have a series of C++ classes that I wish to all be identical in functionality, but otherwise not related by inheritance. Effectively, these classes would differ in name only. (These classes will be thrown, and I do not want a catch clause for some base class to gobble up thrown derived objects. There will be derived classes, but I wish to create discrete sets of thrown classes that are always segregated, as far as catch blocks are concerned.)
Of course, the downside to this is duplicating source code. I don't want to have to update N copies of the same code, whenever something needs to be changed.
I have already solved the code duplication problem via #define. But I think it would aid debug-ability if I could leverage templates, instead. The only thing parameterized in the template will be the class name itself.
I attempted the following, which did not work in gcc (w/ c++0x support enabled):
template<typename ClassName>
class ClassName
{
public:
ClassName(int foo, float bar) { ... }
~ClassName() { ... }
bool SomePublicMethod() { ... }
private:
...
}
Then I would declare the actual classes with something akin to:
typedef ClassName<UnrelatedClass1> UnrelatedClass1;
typedef ClassName<UnrelatedClass2> UnrelatedClass2;
I already know that the above does not work; I am providing it as a conceptual example of what I would like to accomplish, and am wondering if there is a way to make it work, other than the #define macro method that I am presently using (which suffers from diminished debug-ability.)
Use value specialized template:
template<int ID>
class ClassName
{
public:
ClassName(int foo, float bar) { ... }
~ClassName() { ... }
bool SomePublicMethod() { ... }
private:
...
}
typedef ClassName<1> UnrelatedClass1;
typedef ClassName<2> UnrelatedClass2;
This doesn't sound like a very good idea at all.
Exceptions classes should capture a specific type of error, with inheritance used to more generalise the type of error.
So for example you might have a 'disk crashed exception', which more generally might be a 'disk exception' and more generally and 'io exception' and always at its core an 'std::exception'
If all your exceptions are catching different types/classes of error, then why would they all have the same type of implementation.
Also it's uncommon to see #define mixed in the templates because that invariably makes it less readable when there is a compiler error (even if it seems more readable when it is no causing errors).
Perhaps you could provide more information about what is implemented in your exception classes, and I can see if I can help you further.
I do agree with others when they say that you should use inheritance. It is great for many purposes (one of them being the reason why you would like to have similar classes). It is not compulsory to write derived classes only when the objects are related - it is great even if just the functionality that is matching because your idea really is to put similar code together.
However, since your query was about creating multiple classes and we do not have enough view of your project, I believe it is possible that you may really need separate classes. One way of doing this is through macros. Here's a sample:
#include <iostream>
using std::cout;
using std::endl;
#define CUSTOM_CLASS(_CL) class _CL\
{\
public:\
_CL(int foo, float bar) { cout << "Creating instance with foo=" << foo << ";bar=" << bar << endl;}\
~_CL() { }\
bool SomePublicMethod() { cout << "Class created\n"; }\
};
CUSTOM_CLASS(myclass1);
CUSTOM_CLASS(myclass2);
int main()
{
myclass1 instance1(1, 1.3f);
myclass2 instance2(2, 0.3f);
return 0;
}
If you run this using g++, you will get the following result:
Creating instance with foo=1;bar=1.3
Creating instance with foo=2;bar=0.3

Testing a c++ class for features

I have a set of classes that describe a set of logical boxes that can hold things and do things to them. I have
struct IBox // all boxes do these
{
....
}
struct IBoxCanDoX // the power to do X
{
void x();
}
struct IBoxCanDoY // the power to do Y
{
void y();
}
I wonder what is the 'best' or maybe its just 'favorite' idiom for a client of these classes to deal with these optional capabilities
a)
if(typeid(box) == typeid(IBoxCanDoX))
{
IBoxCanDoX *ix = static_cast<IBoxCanDoX*>(box);
ix->x();
}
b)
IBoxCanDoX *ix = dynamic_cast<IBoxCanDoX*>(box);
if(ix)
{
ix->x();
}
c)
if(box->canDoX())
{
IBoxCanDoX *ix = static_cast<IBoxCanDoX*>(box);
ix->x();
}
d) different class struct now
struct IBox
{
void x();
void y();
}
...
box->x(); /// ignored by implementations that dont do x
e) same except
box->x() // 'not implemented' exception thrown
f) explicit test function
if(box->canDoX())
{
box->x();
}
I am sure there are others too.
EDIT:
Just to make the use case clearer
I am exposing this stuff to end users via interactive ui. They can type 'make box do X'. I need to know if box can do x. Or I need to disable the 'make current box do X' command
EDIT2: Thx to all answerers
as Noah Roberts pointed out (a) doesnt work (explains some of my issues !).
I ended up doing (b) and a slight variant
template<class T>
T* GetCurrentBox()
{
if (!current_box)
throw "current box not set";
T* ret = dynamic_cast<T*>(current_box);
if(!ret)
throw "current box doesnt support requested operation";
return ret;
}
...
IBoxCanDoX *ix = GetCurrentBox<IBoxCanDoX>();
ix->x();
and let the UI plumbing deal nicely with the exceptions (I am not really throwing naked strings).
I also intend to explore Visitor
I suggest the Visitor pattern for double-dispatch problems like this in C++:
class IVisitor
{
public:
virtual void Visit(IBoxCanDoX *pBox) = 0;
virtual void Visit(IBoxCanDoY *pBox) = 0;
virtual void Visit(IBox* pBox) = 0;
};
class IBox // all boxes do these
{
public:
virtual void Accept(IVisitor *pVisitor)
{
pVisitor->Visit(this);
}
};
class BoxCanDoY : public IBox
{
public:
virtual void Accept(IVisitor *pVisitor)
{
pVisitor->Visit(this);
}
};
class TestVisitor : public IVisitor
{
public:
// override visit methods to do tests for each type.
};
void Main()
{
BoxCanDoY y;
TestVisitor v;
y.Accept(&v);
}
Of the options you've given, I'd say that b or d are "best". However, the need to do a lot of this sort of thing is often indicative of a poor design, or of a design that would be better implemented in a dynamically typed language rather than in C++.
If you are using the 'I' prefix to mean "interface" as it would mean in Java, which would be done with abstract bases in C++, then your first option will fail to work....so that one's out. I have used it for some things though.
Don't do 'd', it will pollute your hierarchy. Keep your interfaces clean, you'll be glad you did. Thus a Vehicle class doesn't have a pedal() function because only some vehicles can pedal. If a client needs the pedal() function then it really does need to know about those classes that can.
Stay way clear of 'e' for the same reason as 'd' PLUS that it violates the Liskov Substitution Principle. If a client needs to check that a class responds to pedal() before calling it so that it doesn't explode then the best way to do that is to attempt casting to an object that has that function. 'f' is just the same thing with the check.
'c' is superfluous. If you have your hierarchy set up the way it should be then casting to ICanDoX is sufficient to check if x can do X().
Thus 'b' becomes your answer from the options given. However, as Gladfelter demonstrates, there are options you haven't considered in your post.
Edit note: I did not notice that 'c' used a static_cast rather than dynamic. As I mention in an answer about that, the dynamic_cast version is cleaner and should be preferred unless specific situations dictate otherwise. It's similar to the following options in that it pollutes the base interface.
Edit 2: I should note that in regard to 'a', I have used it but I don't use types statically like you have in your post. Any time I've used typeid to split flow based on type it has always been based on something that is registered during runtime. For example, opening the correct dialog to edit some object of unknown type: the dialog governors are registered with a factory based on the type they edit. This keeps me from having to change any of the flow control code when I add/remove/change objects. I generally wouldn't use this option under different circumstances.
A and B require run time type identification(RTTI) and might be slower if you are doing a lot checks. Personally I don't like the solutions of "canDoX" methods, if situations like this arise the design probably needs an upgrade because you are exposing information that is not relevant to the class.
If you only need to execute X or Y, depending on the class, I would go for a virtual method in IBox which get overridden in subclasses.
class IBox{
virtual void doThing();
}
class IBoxCanDoX: public IBox{
void doThing() { doX(); }
void doX();
}
class IBoxCanDoY: public IBox{
void doThing() { doY(); }
void doY();
}
box->doThing();
If that solution is not applicable or you need more complex logic, then look at the Visitor design pattern. But keep in mind that the visitor pattern is not very flexible when you add new classes regularly or methods change/are added/are removed (but that also goes true for your proposed alternatives).
If you are trying to call either of these classes actions from contingent parts of code, you I would suggest you wrap that code in a template function and name each class's methods the same way to implement duck typing, thus your client code would look like this.
template<class box>
void box_do_xory(box BOX){
BOX.xory();
}
There is no general answer to your question. Everything depends. I can say only that:
- don't use a), use b) instead
- b) is nice, requires least code, no need for dummy methods, but dynamic_cast is a little slow
- c) is similar to b) but it is faster (no dynamic_cast) and requires more memory
- e) has no sense, you still need to discover if you can call the method so the exception is not thrown
- d) is better then f) (less code to write)
- d) e) and f) produce more garbage code then others, but are faster and less memory consuming
I assume that you will not only be working with one object of one type here.
I would lay out the data that you are working with and try to see how you can lay it out in memory in order to do data-driven programming. A good layout in memory should reflect the way that you store the data in your classes and how the classes are layed out in memory. Once you have that basic design structured (shouldn't take more than a napkin), I would begin organizing the objects into lists dependent on the operations that you plan to do on the data. If you plan to do X() on a collection of objects { Y } in the subset X, I would probably make sure to have a static array of Y that I create from the beginning. If you wish to access the entire of X occasionally, that can be arranged by collecting the lists into a dynamic list of pointers (using std::vector or your favorite choice).
I hope that makes sense, but once implemented it gives simple straight solutions that are easy to understand and easy to work with.
There is a generic way to test if a class supports a certain concept and then to execute the most appropriate code. It uses SFINAE hack. This example is inspired by Abrahams and Gurtovoy's "C++ Template Metaprogramming" book. The function doIt will use x method if it is present, otherwise it will use y method. You can extend CanDo structure to test for other methods as well. You can test as many methods as you wish, as long as the overloads of doIt can be resolved uniquely.
#include <iostream>
#include <boost/config.hpp>
#include <boost/utility/enable_if.hpp>
typedef char yes; // sizeof(yes) == 1
typedef char (&no)[2]; // sizeof(no) == 2
template<typename T>
struct CanDo {
template<typename U, void (U::*)()>
struct ptr_to_mem {};
template<typename U>
static yes testX(ptr_to_mem<U, &U::x>*);
template<typename U>
static no testX(...);
BOOST_STATIC_CONSTANT(bool, value = sizeof(testX<T>(0)) == sizeof(yes));
};
struct DoX {
void x() { std::cout << "doing x...\n"; }
};
struct DoAnotherX {
void x() { std::cout << "doing another x...\n"; }
};
struct DoY {
void y() { std::cout << "doing y...\n"; }
};
struct DoAnotherY {
void y() { std::cout << "doing another y...\n"; }
};
template <typename Action>
typename boost::enable_if<CanDo<Action> >::type
doIt(Action* a) {
a->x();
}
template <typename Action>
typename boost::disable_if<CanDo<Action> >::type
doIt(Action* a) {
a->y();
}
int main() {
DoX doX;
DoAnotherX doAnotherX;
DoY doY;
DoAnotherY doAnotherY;
doIt(&doX);
doIt(&doAnotherX);
doIt(&doY);
doIt(&doAnotherY);
}