Problem in short:
How could one implement static if
functionality, proposed in c++11, in plain c++ ?
History and original problem:
Recently I came up with a problem like this. I need a class Sender
with an interface like
class Sender
{
void sendMessage( ... );
void sendRequest( ... );
void sendFile( ... );
// lots of different send methods, not important actually
}
In some cases I will need to create a DoubleSender, i.e. an instance of this class, which would call its methods twice, i.e. when calling, let's say, a sendMessage(...)
method, the same message has to be sent twice.
My solutions:
First approach:
Have an isDouble
member, and in the end of each method call make a check
sendMessage(...) { ... if( isDouble ) { sendMessage( ... ); }
Well, I don't want this, because actually I will need double posting very recently, and this part of code in time-critical section will be 98% passive.
Second approach:
Inherit a class DoubleSender
from Sender
, and implement its methods like:
void DoubleSender::sendMessage( ... )
{
Sender::sendMessage(...);
Sender::sendMessage(...);
}
Well, this is acceptable, but takes much space of unpleasant code (really much, because there are lots of different send..
methods.
Third approach:
Imagine that I am using c++11 :). Then I can make this class generic and produce the necessary part of code according to tempalte argument using static if
:
enum SenderType { Single, Double };
template<SenderType T>
class Sender
{
void sendMessage(...)
{
// do stuff
static if ( T == Single )
{
sendMessage(...);
}
}
};
This is shorter, easier to read than previous solutions, does not generate additional code and... it's c++11, which I unfortunately cannot use in my work.
So, here is where I came to my question - how can I implement static if
analog in c++ ?
Also, I would appreciate any other suggestions about how to solve my original problem.
Thanks in advance.
Most compilers do constant folding and dead code removal, so if you write a regular if statement like this:
The if branch will get removed when the code is generated.
The need for
static if
is when the statements would cause a compiler error. So say you had something like this(its somewhat psuedo code):Since you can't call
+=
on non-random access iterators, then the code would always fail to compile with a regular if statement, even with dead code removal. Because the compiler still will check the syntax for before removing the code. When usingstatic if
the compiler will skip checking the syntax if the condition is not true.Quoting @JohannesSchaubLitb
(see also here)
This trick involves a specific GCC interpretation of the specs on Lambdas in C++11. As such, it will (likely) become a defect report against the standard. This will lead to the trick no longer working in more recent version of GCC (it already doesn't work in 4.7).
http://ideone.com/KytVv:
Why not make the send implementation a policy of the sender class and use CRTP:
The public
sendXXX
functions in you class simply forward to the call wrapper, passing in a member function that implements the real functionality. This member function will be called according to theSendPolicy
of the class. CRTP saves the use of bind to wrap the arguments and this pointer up with the member function to call.With one function it doesn't really cut down on the amount of code, but if you have a lot of calls it could help.
Note: This code is a skeleton to provide a possible solution, it has not been compiled.
Note:
Sender<DoubleSenderPolicy>
andSender<SingleSenderPolicy>
are completely different types and do not share a dynamic inheritance relationship.