static if in plain c++? - c++

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.

Quoting #JohannesSchaubLitb
with my static_if that works on gcc one can do it :)
in some limited fashion
(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).
See the comment thread below for some more details from Johanness
http://ideone.com/KytVv:
#include <iostream>
namespace detail {
template<bool C>
struct call_if { template<typename F> void operator<<(F) { } };
template<>
struct call_if<true> {
template<typename F>
void operator<<(F f) { f(); }
};
}
#define static_if(cond) detail::call_if<cond>() << [&]
template<bool C, typename T>
void f(T t) {
static_if(C) {
t.foo();
};
}
int main() {
f<false>(42);
}

Why not make the send implementation a policy of the sender class and use CRTP:
template<class Derived>
class SingleSenderPolicy
{
public:
template< class memFunc >
void callWrapperImpl(memFunc f, ...)
{
static_cast<Derived *>(this)->f(...);
}
};
template< class Derived >
class DoubleSenderPolicy
{
public:
template< class memFunc >
void callWrapperImpl(memFunc f, ...)
{
static_cast<Derived *>(this)->f(...);
static_cast<Derived *>(this)->f(...);
}
};
template< class SendPolicy>
class Sender : public SendPolicy< Sender >
{
public:
void sendMessage( ... )
{
// call the policy to do the sending, passing in a member function that
// acutally performs the action
callWrapperImpl( &Sender::sendMessageImpl, ... );
}
void doSomethingElse( ... )
{
callWrapperImpl( &Sender::doSomethingElseImpl, ... );
}
protected:
void sendMessageImpl(... )
{
// Do the sending here
}
void doSomethingElseImpl(... )
{
// Do the sending here
}
};
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 the SendPolicy 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> and Sender<SingleSenderPolicy> are completely different types and do not share a dynamic inheritance relationship.

Most compilers do constant folding and dead code removal, so if you write a regular if statement like this:
enum SenderType { Single, Double };
template<SenderType T>
class Sender
{
void sendMessage(...)
{
// do stuff
if ( T == Single )
{
sendMessage(...);
}
}
};
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):
static if (it == random_access_iterator)
{
it += n;
}
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 using static if the compiler will skip checking the syntax if the condition is not true.

std::string a("hello world");
// bool a = true;
if(std::is_same<std::string, decltype(a)>::value) {
std::string &la = *(std::string*)&a;
std::cout << "std::string " << la.c_str() << std::endl;
} else {
bool &la = *(bool*)&a;
std::cout << "other type" << std::endl;
}

Related

Save template type parameter pack for later use

I'm working on a code where I can bind events and callbacks to react to those events, the interface looks like this:
void on_close();
struct S
{
void the_app_is_closing();
};
S s;
Events::Register(app::CLOSE, on_close);
Events::Register(app::CLOSE, s, &S::the_app_is_closing);
...
...
if (/* something happens */)
Events::Broadcast(app::CLOSE);
Internally it keeps a container which associates an enum value identifying an event with all the functions expected to react to that event. Those functions are kept into an object which can hold free functions or member functions and feeds the functions through a template function (apply) that forwards the parameters:
class callback
{
struct base {};
template <typename ... params_pack>
struct callable : public base
{
callable(void(*a_function)(params_pack ...)) :
m_call{a_function}
{}
template <typename listener_t>
callable(listener_t &a_listener, void(listener_t:: *a_function)(params_pack ...)) :
m_call{[&a_listener, &a_function](params_pack ... a_argument)
{
(a_listener.*a_function)(a_argument ...);
}}
{}
std::function<void(params_pack ...)> m_call;
};
template <typename ... params_pack>
auto build(void(*a_function)(params_pack ...))
{
return std::make_unique<callable<params_pack ...>>(a_function);
}
template <typename listener_t, typename ... params_pack>
auto build(listener_t &a_listener, void(listener_t:: *a_function)(params_pack ...))
{
return std::make_unique<callable<params_pack ...>>(a_listener, a_function);
}
std::unique_ptr<base> m_function{nullptr};
public:
template <typename function_t>
callback(function_t a_function) :
m_function{build(a_function)}
{}
template <typename listener_t, typename function_t>
callback(listener_t &a_listener, function_t a_function) :
m_function{build(a_listener, a_function)}
{}
template <typename ... params_pack>
void apply(params_pack ... a_argument) const
{
if (auto &call = *static_cast<callable<params_pack ...> *>(m_function.get());
std::is_invocable_v<decltype(call.m_call), params_pack ...>)
{
call.m_call(a_argument ...);
}
}
};
I have an important bug on that apply function that can be reproduced with this code:
void string_parameter(const std::string &s) { std::cout << s << '\n'; }
void long_parameter(long l) { std::cout << l << '\n'; }
int main()
{
callback l(long_parameter);
callback s(string_parameter);
l.apply(123);
s.apply("Test");
return 0;
}
Even if you can call string_parameter directly with a literal string and long_parameter directly with a literal integer, doing the call through callback::apply messes everything up. I know why it is happening:
I'm static_casting callback::callable<const std::string &> to callback::callable<const char *>.
Then the callable::m_call which underlying type is std::function<const std::string &> thinks it is std::function<const char *>.
The callable::m_call receives a literal string but is reinterpreted as std::string during the std::function call, creating the mess.
Same story with long and int.
The solution would be to save the parameter pack used on construction in order to use it inside apply:
template <typename function_t>
callback(function_t a_function) :
m_function{build(a_function)}
{ PARAMETERS = function_t.parameters } // ???
template <typename listener_t, typename function_t>
callback(listener_t &a_listener, function_t a_function) :
m_function{build(a_listener, a_function)}
{ PARAMETERS = function_t.parameters } // ???
...
...
template <typename ... params_pack>
void apply(params_pack ... a_argument) const
{
// Saved parameters --> vvvvvvvvvvvvvv
if (auto &call = *static_cast<callable<PARAMETERS ...> *>(m_function.get());
std::is_invocable_v<decltype(call.m_call), params_pack ...>)
{
call.m_call(a_argument ...);
}
}
But I don't know if this is even possible. Any advise?
Thanks!
tl;dr:
Completely abstracting away the signature of the function AND still calling it in a type-safe way is impossible in C++
A type-based event system could be a good alternative
1. Why it's impossible to do what you're asking for
1.1 How Type-Erasure works
Type-erasure is fundamentally based on polymorphism. By defining a set of methods that all objects we want to store have in common (the interface) we don't need to know the actual type we're dealing with.
There is no way to do type-erasure without involving polymorphism.
For example, a very crude implementation of std::function could look like this:
template<class RetVal, class... Args>
class function {
public:
template<class U>
function(U u) : ptr(new impl<U>(u)) {}
~function() { delete ptr; }
RetVal operator()(Args... args) {
return ptr->call(args...);
}
private:
struct base {
virtual ~base() = default;
virtual RetVal call(Args... args) = 0;
};
template<class T>
struct impl : base {
impl(T t): t(t) {}
RetVal call(Args... args) override {
return t(args...);
}
private:
T t;
};
base* ptr;
};
template<class RetVal, class... Args>
class function<RetVal(Args...)> : public function<RetVal, Args...> {};
godbolt example
This is how std::function accomplishes to store any function object that is compatible with it's signature - it declares an interface (base) that will be used by all function objects (impl).
The interface only consists of 2 functions in this case:
The destructor (we need to know how to properly cleanup the function object)
The call() function (for invoking the actual function)
Sidenote 1: A real std::function implementation would need a couple more interface functions, e.g. for copying / moving the callable
Sidenote 2: Your existing implementation has a small bug: struct base MUST have a virtual destructor, otherwise the destructor of struct callable would never be called, resulting in undefined behaviour.
1.2 How your callable would need to work
What you want is an object that completely erases both the function object AND the parameters that you pass.
But what should your interface then look like?
struct base {
virtual ~base() = default;
virtual ??? call(???); // how should this work?
};
This is the underlying problem you're facing - it's impossible to define an interface for your callable - because you don't know what the arguments are gonna be.
This is what #Yakk - Adam Nevraumont implied with "non-uniform" objects - there is no definition of call() that can handle all potential function types.
1.3 Options
So at that point you basically have two options:
Don't erase the function type (like #Yakk - Adam Nevraumont suggested)
Sacrifice compile-time type safety and maintainability by creating an interface that can deal with arbitrary function types
The latter option is what your code currently uses - either the function parameters match or your code has undefined behaviour.
A few other ways to implement it that don't rely on undefined behaviour could be:
Add an interface function for each possible argument combination
struct base {
/* ... */
// All possible ways a `callable` could potentially be invoked
virtual void call(int val0) { throw std::exception("invalid call"); };
virtual void call(std::string val0) { throw std::exception("invalid call"); };
virtual void call(const char* val0) { throw std::exception("invalid call"); };
virtual void call(int val0, std::string val1) { throw std::exception("invalid call"); };
virtual void call(int val0, const char* val1) { throw std::exception("invalid call"); };
// etc...
}
// then implement the ones that are sensible
struct callable<std::string> : public base {
/* ... */
void call(std::string val0) override { /* ... */ }
void call(const char* val0) override { /* ... */ }
}
This obviously gets out of hand rather quickly.
"Accept anything" interface
struct base {
/* ... */
virtual void call(std::any* arr, int length);
};
// then implement the ones that are sensible
struct callable<std::string> : public base {
/* ... */
void call(std::any* arr, int length) override {
if(length != 1) throw new std::exception("invalid arg count");
// will throw if first argument is not a std::string
std::string& value = std::any_cast<std::string&>(arr[0]);
/* ... */
}
};
A bit better, but still looses compile-time type safety.
1.4 Conclusion
Compile-time type-safety with type-erasure is only possible if there is an uniform interface for all possible objects.
It is technically possible to type-erase non-uniform objects, but if you do that you'll loose compile-time type-safety (and need to do those checks at runtime instead)
2. Another Approach: Type-Based Event System
I'd like to propose a different way to handle the events that allows you to have arbitrary events without having to hard-code them into your Events class.
2.1 Basic Functionality
The main idea of this implementation is to have a class for each event you'd want to have that contains the parameters for the given event, e.g.:
struct AppClosingEvent {
const std::string message;
const int exitCode;
};
struct BananaPeeledEvent {
const std::shared_ptr<Banana> banana;
const std::shared_ptr<Person> peeler;
};
// etc...
This would then allow you to use the type of the event struct as a key for your event listeners.
A very simple implementation of this event system could look like this: (ignoring unregistration for now)
class EventBus {
private:
using EventMap = std::multimap<std::type_index, std::function<void(void*)>>;
// Adds an event listener for a specific event
template<class EvtCls, class Callable>
requires std::is_invocable_v<Callable, EvtCls&>
inline void Register(Callable&& callable) {
callbacks.emplace(
typeid(EvtCls),
[cb = std::forward<Callable>(callable)](void* evt) {
cb(*static_cast<EvtCls*>(evt));
}
);
}
// Broadcasts the given event to all registered event listeners
template<class EvtCls>
inline void Broadcast(EvtCls& evt) {
auto [first, last] = callbacks.equal_range(typeid(EvtCls));
for(auto it = first; it != last; ++it)
(it->second)(&evt);
}
private:
EventMap callbacks;
};
Register() takes a callable object that needs to be invocable with the given event type. Then it type-erases the callable so we can store it as a std::function<void(void*>
Broadcast(evt) looks up all event listeners that are registered based on the type of the event object and calls them.
Example Usage would look like this:
EventBus bus;
bus.Register<AppClosingEvent>([](AppClosingEvent& evt) {
std::cout << "App is closing! Message: " << evt.message << std::endl;
});
bus.Register<BananaPeeledEvent>([](BananaPeeledEvent& evt) {
// TODO: Handle banana peeling
});
AppClosingEvent evt{"Shutting down", 0};
bus.Broadcast(evt);
By using the type of the event as the key both Register() and Broadcast() are completely type-safe - it's impossible to register a function with incompatible function arguments.
Additionally the EventBus class doesn't need to know anything about the events it'll handle - adding a new event is as simple as defining a new class with the members you need for your event.
2.2 Adding the ability to unregister an event listener
I chose to use a multimap in this case because they guarantee to not invalidate iterators, unless the element the iterator points to itself gets removed from the multimap - which allows us to use a multimap iterator as the registration token for the event handler.
Full implementation: godbolt example
/*
EventBus - allows you to register listeners for arbitrary events via `.Register()`
and then later invoke all registered listeners for an event type with `.Broadcast()`.
Events are passed as lvalues, to allow event handlers to interact with the event, if required.
*/
class EventBus {
private:
using EventMap = std::multimap<std::type_index, std::function<void(void*)>>;
public:
/*
Represents a registered event handler on the EventBus.
Works a lot like std::unique_ptr (it is movable but not copyable)
Will automatically unregister the associated event handler on destruction.
You can call `.disconnect()` to unregister the event handler manually.
*/
class Connection {
private:
friend class EventBus;
// Internal constructor used by EventBus::Register
inline Connection(EventBus& bus, EventMap::iterator it) : bus(&bus), it(it) { }
public:
inline Connection() : bus(nullptr), it() {}
// not copyable
inline Connection(Connection const&) = delete;
inline Connection& operator=(Connection const&) = delete;
// but movable
inline Connection(Connection&& other)
: bus(other.bus), it(other.it) {
other.detach();
}
inline Connection& operator=(Connection&& other) {
if(this != &other) {
disconnect();
bus = other.bus;
it = other.it;
other.detach();
}
return *this;
}
inline ~Connection() {
disconnect();
}
// Allows to manually unregister the associated event handler
inline void disconnect() {
if(bus) {
bus->callbacks.erase(it);
detach();
}
}
// Releases the associated event handler without unregistering
// Warning: After calling this method it becomes impossible to unregister
// the associated event handler.
inline void detach() {
bus = nullptr;
it = {};
}
private:
EventBus* bus;
EventMap::iterator it;
};
// Adds an event listener for a specific event
template<class EvtCls, class Callable>
requires std::is_invocable_v<Callable, EvtCls&>
inline Connection Register(Callable&& callable) {
auto it = callbacks.emplace(
typeid(EvtCls),
[cb = std::forward<Callable>(callable)](void* evt) {
cb(*static_cast<EvtCls*>(evt));
}
);
return { *this, it };
}
// Broadcasts the given event to all registered event listeners
template<class EvtCls>
inline void Broadcast(EvtCls& evt) {
auto [first, last] = callbacks.equal_range(typeid(EvtCls));
for(auto it = first; it != last;)
(it++)->second(&evt);
}
private:
EventMap callbacks;
};
With this you can easily register listeners and unregister them later (e.g. if the class they're bound to gets destructed)
Example:
struct DispenseNachosEvent {};
struct DispenseCheeseEvent {};
class NachoMachine {
public:
NachoMachine(EventBus& bus) {
// register using std::bind
nachoEvent = bus.Register<DispenseNachosEvent>(
std::bind(
&NachoMachine::OnDispenseNachos,
this,
std::placeholders::_1
)
);
// register with lambda
cheeseEvent = bus.Register<DispenseCheeseEvent>(
[&](DispenseCheeseEvent& evt) {
OnDispenseCheese(evt);
}
);
}
// Default destructor will automatically
// disconnect both event listeners
private:
void OnDispenseNachos(DispenseNachosEvent&) {
std::cout << "Dispensing Nachos..." << std::endl;
}
void OnDispenseCheese(DispenseCheeseEvent&) {
std::cout << "Dispensing Cheese..." << std::endl;
}
private:
EventBus::Connection nachoEvent;
EventBus::Connection cheeseEvent;
};
2.3 Other benefits
If you want you can also allow the event handlers to modify the event object - e.g. cancel it - which allows you to return state to the piece of code that called Broadcast()
Example:
struct CancelableExampleEvent {
inline void Cancel() { isCancelled = true; }
inline bool IsCancelled() { return isCancelled; }
CancelableExampleEvent(std::string message) : message(message) {}
const std::string message;
private:
bool isCancelled = false;
};
// Usage:
CancelableExampleEvent evt;
bus.Broadcast(evt);
if(!evt.IsCancelled()) {
// TODO: Do something
}
Event Handlers can remove themselves - this is usually tricky to implement due to iterators being invalidated, but with multimaps it's rather easy to implement:
template<class EvtCls>
inline void Broadcast(EvtCls& evt) {
auto [first, last] = callbacks.equal_range(typeid(EvtCls));
for(auto it = first; it != last;)
(it++)->second(&evt);
}
By incrementing it before calling the function we make sure that it remains valid, even if the event handler chooses to unregister itself as part of its callback.
e.g. this would work:
EventBus::Connection con;
con = bus.Register<SomeEvent>([&con](SomeEvent&){
std::cout << "Received event once!" << std::endl;
con.disconnect();
});
2.4 Try it online!
Here's a godbolt that contains the entire code of this post to try it out.
This is your problem:
class callback
it should be
template<class...Args>
class callback
because you have to think about what happens when the types do not match
void string_parameter(const std::string &s) { std::cout << s << '\n'; }
void long_parameter(long l) { std::cout << l << '\n'; }
callback<long> l(long_parameter);
callback<std::string> s(string_parameter);
l.apply(123);
s.apply("Test");
which works flawlessly.
Now you run into the problem of a central enum for all callbacks.
Events::Register(app::CLOSE, on_close);
Events::Register(app::CLOSE, s, &S::the_app_is_closing);
The problem is that all use of app::CLOSE must know what the signature of the callback must be. The code registering it must know, and the code invoking the callback must know.
Your design, however, carefully forgets this fact, and forces type unsafety at both ends. Then you add so,e template code in the middle to ferry types around... which even if it did work, would be work for no good reason.
template<app::event e>
void Events::Register(event_sig<e>* pf);
template<app::event e, class T>
void Events::Register(T* pt, event_mem_sig<T,e>* pf);
template<app::event e, class...Ts>
void Event::Broadcast(Ts&&....ts);
here we have a more sensible API. The event type is compile time value, so we can do type checking, and store the event callbacks in a type safe list.
...
Now, if you have a reasonably bounded number of events (ie, not 1000s of which under 1% are subscribed to), an even simpler solution is to make an event queue an actual object, instead of an enum and traits.
using token=std::shared_ptr<void>;
template<class...Args>
struct broadcaster {
size_t broadcast(Ts...ts)const;
token subscribe(std::function<void(Ts...)>);
void unsafe_subscribe(void(*)(Ts...));
// IMPLEMENTATION
};
now your code becomes
struct Events {
broadcaster<> appClosing;
};
Events g_events;
struct S
{
void the_app_is_closing();
token listening;
};
S s;
s.listening=g_events.appClosing.subscribe(&s, &S::the_app_is_closing);
g_events.appClosing.unsafe_subscribe(on_close);
g_events.appClosing.broadcast();
The types of the arguments are now tied to the appClosing object, so it is checked at both sibscription and at broadcast, conversion is done automatically.
Here each broadcaster maintains its own listener queue (hence bit above about "1000s of event types most unused). Extra work can be done to reduce the queue storage and share it, but that should onlh be done if you need it. And you probably won't.
The enum solution seems like it reduces duplication, but uniform lists of things with non uniform types are often a sign your list shoudln't be uniform.
Members of a struct are a fine way to list non uniform things. Having them be generated from a template means there isn't code writing duplication. And identical signature broadcasters will share binary implementations, somit isn't inefficient.

pointer-to-method callbacks in C++11/14/17?

(A previous question of mine has similar wording and examples, but is asking something quite different.
Before I was asking for ideas for approaches. Now I'm asking how to get a specific approach to work.)
I have some subscription function that will call my callback when something happens. (Let's say it's a timer, and will pass me an object when a certain number of milliseconds elapses.) After looking at lambdas, std:function and std:bind I think the solution of pointers-to-methods is higher performance and simpler to write (especially for the subscriber) but I can't quite figure out the last bit.
This example mirrors my project a bit: we have a framework, represented by Foo, which is written once, and we'll have many subclasses represented here by Bar that will be written by people with more domain knowledge but less C++ knowledge. So, we want that call to SubscribeTimer() to be as simple as possible. Finally the application is high performance and we'd like to eliminate heap usage, including creating implicit std::bind objects and so on.
#include <iostream>
#include <functional>
using namespace std;
class Data { int i; };
class Foo {
public:
typedef void (Foo::*Timer_T)( Data* pd );
virtual void SubscribeTimer( int iMilliseconds, Timer_T pmethod );
virtual void SubscribeTimer( int iMilliseconds, std::function<void(Data*)> pfn ); // undesired
virtual void OnTimerA( Data* pd ) { cout << "Foo::OnTimerA called" << endl; };
};
void Foo::SubscribeTimer( int iMilliseconds, Timer_T pmethod ) {
Data d;
(this->*pmethod)( &d );
}
void Foo::SubscribeTimer( int iMilliseconds, std::function<void(Data*)> pfn ) { // undesired
Data d;
pfn( &d );
}
class Bar: public Foo {
public:
void Init();
virtual void OnTimerA( Data* pd ) { cout << "Bar::OnTimerA called" << endl; };
virtual void OnTimerB( Data* pd ) { cout << "Bar::OnTimerB called" << endl; };
};
void Bar::Init() {
// Works like I want it to: easy to subscribe, and high performance.
SubscribeTimer( 1000, &Foo::OnTimerA );
// What I'd like to do, but doesn't work.
//SubscribeTimer( 1000, &Bar::OnTimerB );
// Does exactly what I want except more complicated to write and I believe slower to run.
SubscribeTimer( 1000, std::bind( &Bar::OnTimerB, this, std::placeholders::_1 ) );
}
int main( int nArg, const char* apszArg[] ) {
Bar bar;
bar.Init();
}
As expected (if you overlook the requirement to write Foo::, not Bar:: in Init()'s call to SubscribeTimer()) the program outputs:
Bar::OnTimerA called (from the version of SubscribeTimer() I like)
Bar::OnTimerB called (from the version of SubscribeTimer() I think is too verbose/slow)
So this example works perfectly and does what I need... except that the subclass can only register handlers for method names the superclass has thought to define, whether or not they are defined or not. In reality, though, the subclass may wish to register many handlers for different events, with names tha superclass wouldn't know.
So in a sentence: how can I pass OnTimerB() into the method-pointer version of SubscribeTimer()? I'm happy to change Timer_T definition, SubscribeTimer() or whatever. As a floor though, there is no point in a member-pointer solution more complicated for the subclass than the std::function implementation, and no point in a solution slower than thestd::function implementation either. On the other hand, added complexity in the superclass isn't a problem, as it's write-once code.
To call Bar::OnTimerB, you need a pointer of type Bar. You therefore need to implement some kind of type erasure.
class Foo {
public:
template <typename Derived>
void SubscribeTimer(int iMilliseconds, void (Derived::*pmethod)(Data* pd)) {
auto const self = static_cast<Derived*>(this);
Data d;
(self->*pmethod)(&d);
}
};
Obviously, if you are going to have the callback invoked later, then you need to store this somehow. This is what std::function<> abstracts away for you. You could, of course, do that yourself, but std::function<> isn't that bad, especially on platforms with the small-function optimization.
You could therefore do the std::function wrapper internally:
template <typename Derived>
void SubscribeTimer(int iMilliseconds, void (Derived::*pmethod)(Data* pd)) {
SubscribeTimer(iMilliseconds,
[self = static_cast<Derived*>(this), pmethod](Data* pd) {
(self->*pmethod)(pd);
});
}

Uses of pointers non-type template parameters?

Has anyone ever used pointers/references/pointer-to-member (non-type) template parameters?
I'm not aware of any (sane/real-world) scenario in which that C++ feature should be used as a best-practice.
Demonstation of the feature (for pointers):
template <int* Pointer> struct SomeStruct {};
int someGlobal = 5;
SomeStruct<&someGlobal> someStruct; // legal c++ code, what's the use?
Any enlightenment will be much appreciated!
Pointer-to-function:
Pointer-to-member-function and pointer-to-function non-type parameters are really useful for some delegates. It allows you to make really fast delegates.
Ex:
#include <iostream>
struct CallIntDelegate
{
virtual void operator()(int i) const = 0;
};
template<typename O, void (O::*func)(int)>
struct IntCaller : public CallIntDelegate
{
IntCaller(O* obj) : object(obj) {}
void operator()(int i) const
{
// This line can easily optimized by the compiler
// in object->func(i) (= normal function call, not pointer-to-member call)
// Pointer-to-member calls are slower than regular function calls
(object->*func)(i);
}
private:
O* object;
};
void set(const CallIntDelegate& setValue)
{
setValue(42);
}
class test
{
public:
void printAnswer(int i)
{
std::cout << "The answer is " << 2 * i << "\n";
}
};
int main()
{
test obj;
set(IntCaller<test,&test::printAnswer>(&obj));
}
Live example here.
Pointer-to-data:
You can use such non-type parameters to extend the visibility of a variable.
For example, if you were coding a reflexion library (which might very useful for scripting), using a macro to let the user declare his classes for the library, you might want to store all data in a complex structure (which may change over time), and want some handle to use it.
Example:
#include <iostream>
#include <memory>
struct complex_struct
{
void (*doSmth)();
};
struct complex_struct_handle
{
// functions
virtual void doSmth() = 0;
};
template<complex_struct* S>
struct csh_imp : public complex_struct_handle
{
// implement function using S
void doSmth()
{
// Optimization: simple pointer-to-member call,
// instead of:
// retrieve pointer-to-member, then call it.
// And I think it can even be more optimized by the compiler.
S->doSmth();
}
};
class test
{
public:
/* This function is generated by some macros
The static variable is not made at class scope
because the initialization of static class variables
have to be done at namespace scope.
IE:
class blah
{
SOME_MACRO(params)
};
instead of:
class blah
{
SOME_MACRO1(params)
};
SOME_MACRO2(blah,other_params);
The pointer-to-data template parameter allows the variable
to be used outside of the function.
*/
std::auto_ptr<complex_struct_handle> getHandle() const
{
static complex_struct myStruct = { &test::print };
return std::auto_ptr<complex_struct_handle>(new csh_imp<&myStruct>());
}
static void print()
{
std::cout << "print 42!\n";
}
};
int main()
{
test obj;
obj.getHandle()->doSmth();
}
Sorry for the auto_ptr, shared_ptr is available neither on Codepad nor Ideone.
Live example.
The case for a pointer to member is substantially different from pointers to data or references.
Pointer to members as template parameters can be useful if you want to specify a member function to call (or a data member to access) but you don't want to put the objects in a specific hierarchy (otherwise a virtual method is normally enough).
For example:
#include <stdio.h>
struct Button
{
virtual ~Button() {}
virtual void click() = 0;
};
template<class Receiver, void (Receiver::*action)()>
struct GuiButton : Button
{
Receiver *receiver;
GuiButton(Receiver *receiver) : receiver(receiver) { }
void click() { (receiver->*action)(); }
};
// Note that Foo knows nothing about the gui library
struct Foo
{
void Action1() { puts("Action 1\n"); }
};
int main()
{
Foo foo;
Button *btn = new GuiButton<Foo, &Foo::Action1>(&foo);
btn->click();
return 0;
}
Pointers or references to global objects can be useful if you don't want to pay an extra runtime price for the access because the template instantiation will access the specified object using a constant (load-time resolved) address and not an indirect access like it would happen using a regular pointer or reference.
The price to pay is however a new template instantiation for each object and indeed it's hard to think to a real world case in which this could be useful.
The Performance TR has a few example where non-type templates are used to abstract how the hardware is accessed (the hardware stuff starts at page 90; uses of pointers as template arguments are, e.g., on page 113). For example, memory mapped I/O registered would use a fixed pointer to the hardware area. Although I haven't ever used it myself (I only showed Jan Kristofferson how to do it) I'm pretty sure that it is used for development of some embedded devices.
It is common to use pointer template arguments to leverage SFINAE. This is especially useful if you have two similar overloads which you couldn't use std::enable_if default arguments for, as they would cause a redefinition error.
This code would cause a redefinition error:
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
void foo (T x)
{
cout << "integral";
}
template <typename T, typename = std::enable_if_t<std::is_floating_point<T>::value>>
void foo (T x)
{
cout << "floating";
}
But this code, which utilises the fact that valid std::enable_if_t constructs collapse to void by default, is fine:
// This will become void* = nullptr
template <typename T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
void foo (T x)
{
cout << "integral";
}
template <typename T, std::enable_if_t<std::is_floating_point<T>::value>* = nullptr>
void foo (T x)
{
cout << "floating";
}
Occasionally you need to supply a callback function having a particular signature as a function pointer (e.g. void (*)(int)), but the function you want to supply takes different (though compatible) parameters (e.g. double my_callback(double x)), so you can't pass its address directly. In addition, you might want to do some work before and after calling the function.
It's easy enough to write a class template that tucks away the function pointer and then calls it from inside its operator()() or some other member function, but this doesn't provide a way to extract a regular function pointer, since the entity being called still requires the this pointer to find the callback function.
You can solve this problem in an elegant and typesafe way by building an adaptor that, given an input function, produces a customised static member function (which, like a regular function and unlike a non-static member function, can have its address taken and used for a function pointer). A function-pointer template parameter is needed to embed knowledge of the callback function into the static member function. The technique is demonstrated here.

Copy-and-swap done through interfaces

I'm trying to implement a copy+swap idiom to achieve strong-exception safety through a level of abstraction and, although the principle is clear, as it's often the case the devil is in the detail.
Say I have a class that looks like this:
class AConcreteType :
public ISomething,
public ISwappable
{
public:
// From ISwappable
void Swap( ISwappable& );
};
I can now do this within a method that only deals with ISomething:
void AClass::DoSomething( ISomething& something )
{
// say there is a function that allows me to clone 'something'
// Probably it ought to go into an auto_ptr, but for clarity:
ISomething& somethingElse( clone( something ) );
// ... so that at the end, after doing stuff with somethingElese I can do
ISwappable& swappable1 = dynamic_cast<ISwappable&>( something );
ISwappable& swappable2 = dynamic_cast<ISwappable&>( somethingElse );
// ... I may want to check that the concrete types behind the interface are
// actually the same too with something like typeid, but I'll leave that out for clarity
swappable1.Swap( swappable2 );
}
where
void AConcreteType::Swap( ISwappable& swappable )
{
AConcreteType& somethingConcrete = dynamic_cast<AConcreteType&>(swappable);
std::swap( *this, somethingConcrete );
}
This all works, as all the dynamic_casts are on references, which is an operation that throws when the type is not supported; this leaves my objects in a good state as the swap doesn't happen until the very end. But what I'm not comfortable with is the fact that the call swappable1.Swap(swappable2) can still throw (via the same dynamic_cast mechanism), and that would be counter-intuitive for the user of Swap as he would probably not expect anything to throw at that point.
An alternative I thought of was to template ISwappable so as to do away with the dynamic_cast inside the implementation of Swap:
template< typename T >
class ISwappable
{
public:
virtual void Swap( T& ) = 0;
};
so that its implementation is simply
class AConcreteType :
public ISomething,
public ISwappable<AConcreteType>
{
void Swap( AConcreteType& act ) { std::swap( *this, act ); }
};
This allows the Swap call to be non-throw (and allows me to guarantee that the two objects are actually swappable at compile-time), but the problem now is that I have to deal with a concrete type inside DoSomething, but I don't have access to AConcreteType inside that function.
Any ideas?
C++ isn't particularly geared toward inheritance based interfaces. For example, you're implementing a function that takes an ISomething, but it also expects the object to be an ISwappable. Languages geared toward using interfaces like this usually have a direct way to express requirements for multiple interfaces on a single type.
Instead it's probably better in C++ to use templates and then express requirements on those template parameters when necessary. Static assertions and type traits are a pretty simple and readable way of doing this in C++.
template<typename T,typename Interface>
struct implements {
static constexpr bool value = std::is_base_of<Interface,T>::value;
}
template<typename T>
void AClass::DoSomething(T &something ) {
static_assert(implements<T,ISomething>::value, "requires ISomething");
static_assert(implements<T,ISwappable<T>>::value, "requires ISwappable");
T somethingElse = clone(something);
something.Swap(somethingElse);
}
You might also want to move away from using inheritance for interfaces altogether. You can usually get the static type checking on your classes via static_asserts and type traits without inheritance:
template<typename T>
struct is_swappable { static constexpr bool value = ... };
class AConcreteType {
...
};
static_assert(is_swappable<AConcreteType>,"...");
template<typename T>
void AClass::DoSomething(T &something ) {
static_assert(is_something<T>::value, "requires something");
static_assert(is_swappable<T>::value, "requires swappable");
If you ask me, the idea of a ISwappable is already "ill-posed" since you cannot swap abstract types into each other without consequences... What you can swap safely are addresses of interfaces (pointers):
std::unique_ptr<ISomething> tI1(new AConcreteType(1)), tI2(new BConcreteType(2));
std::cout << tI1->IdentifyYourSelf() << std::endl; // -> prints "1"
std::cout << tI2->IdentifyYourSelf() << std::endl; // -> prints "2"
tI1.swap(tI2);
// contents are swapped now
std::cout << tI1->IdentifyYourSelf() << std::endl; // -> prints "2"
std::cout << tI2->IdentifyYourSelf() << std::endl; // -> prints "1"

Reducing amount of if/if code (C++)

In my program I have to create an object, which looks like that:
Library::Param1<Library::Param2>::Param3 (don't know how to name Param, types maybe?)
Similar to std::vector<std::string>::iterator.
So, these Param's need to be changed by strings. For example:
if(param1 == "1_VALUE1")
{
if(param2 == "2_VALUE1")
{
MyLib::1_VALUE1<MyLib::2_VALUE1>::Param3 obj;
//Obj is used
}
//15+ similar if-statements, where only 2_VALUE1 changes
}
/*15+ similar if-statements, where only 1_VALUE1 changes,
but the contents remain same (again 15+ if-statements)*/
using namespace MyLib; is not neseccary.
So, I need to reduce amount of those if-statements, but I do not know the way to do it. I think it could be done with templates, but I am not familiar with them, so, I guess, I would need a code sample.
Sorry for the bad english, if any more info is needed - let me know. Thank you.
--- EDIT: Library (CryptoPP) type-definitions:
Since errors are only on Param1, posting one variation of it:
//! CBC mode with ciphertext stealing
template <class CIPHER>
struct CBC_CTS_Mode : public CipherModeDocumentation
{
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, CBC_CTS_Encryption> Encryption;
typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, CBC_CTS_Decryption> Decryption;
};
I agree with Mark B that a factory would be nice, but I'm not sure if this is possible if you do not have a base class that all these types inherit from. If I understand the problem correcty, you have 15 types for Value 1 and 15 types for Value2 which leads to 15*15 if-statements. You can reduce them to 2*15 with the following approach: (untested)
---EDIT1: changed order of methods ---
template
void level2()
{
typename T1_T2::Param3 obj;
doSomething(obj);
}
template <template<class> class T1>
void level1(std::string param2)
{
if (param2 == "2_VALUE1")
level2<T1<MyLib::2_Value1> >();
if (param2 == "2_VALUE1")
level2<T1<MyLib::2_Value2> >();
...
}
void level0(std::string param1, std::string param2)
{
if (param1 == "1_VALUE1")
level1<MyLib::1_Value1>(param2);
if (param2 == "1_VALUE2")
level1<MyLib::1_Value2>(param2);
...
}
--- EDIT2 ---
To help you figure out why you can't compile, you can start with this sample code (compiles on Visual Studio 2008):
void doSomething(int x)
{
}
struct Type2_1 {};
template <class T2>
struct Type1_1
{
typedef int Param3;
};
template <class T2>
struct Type1_2
{
typedef int Param3;
};
template <template<class> class T1>
void level1(std::string param2)
{
if (param2 == "2_VALUE1")
level2<T1<Type2_1> >();
}
void level0(std::string param1, std::string param2)
{
if (param1 == "1_VALUE1")
level1<Type1_1>(param2);
if (param2 == "1_VALUE2")
level1<Type1_2>(param2);
}
template <class T1_T2>
void level2()
{
typename T1_T2::Param3 obj;
doSomething(obj);
}
int main(int argc, char* argv[])
{
level0("1_VALUE1", "2_VALUE1");
return 0;
}
Please note that "doSomething()" should be whatever you want MyLib to do with your obj; Returning obj from level0/1/2 won't work without a base class.
Instead of changing the type dynamically using if statements like that, which isn't well supported by C++, consider using something like a factory pattern instead.
Basically you set up a hierarchy of classes that have virtual methods that implement what you're trying to do in the if cases. You then make a function that creates the appropriate child class from a set of strings, and then you call go or whatever on the created instance.