Reference parameter being copied in variadic template - c++

I have an Event class that stores a set of tuples of weak_ptr (the observer) to a function that gets executed when the event is "fired".
The function type is: void(int &) in the example. That is to say, I want to fire the event passing a reference to a value, to have the observer change that value and to verify that the value was changed back in the observed object. The event implementation is variadic by the way, which may complicate the issue (at least the code).
At the moment this is failing. Somewhere along the line the reference is being converted to a non-reference or copied, but I cannot see where.
Full repo is below. Note assert (value != 10) fails, even though I set the value to 1 in the event handler.
#include <memory>
#include <tuple>
#include <vector>
#include <cassert>
#include <functional>
template<class FunctionPrototype>
class Event
{
public:
template<typename... Args>
void operator()(Args... args)
{
for (auto const & listener : Listeners)
{
if (auto locked = std::get<0>(listener).lock())
std::get<1>(listener)(args...);
}
}
template<typename P, typename Q, typename R, typename... Args>
void Attach(P(Q::*f)(Args...), std::shared_ptr<R> const & p)
{
auto w = std::weak_ptr<R>(p);
auto l = [w, f](Args... args) {
if (auto locked = w.lock())
return (*locked.get().*f)(args...);
else
return P();
};
Listeners.push_back(std::make_tuple(std::weak_ptr<void>(w), l));
}
typedef std::tuple<std::weak_ptr<void>, std::function<FunctionPrototype>> event_tuple;
std::vector<event_tuple> Listeners;
};
class Observed : public std::enable_shared_from_this < Observed >
{
public:
int value;
void Fire()
{
value = 10;
TheEvent(value);
assert(value != 10);
}
Event<void(int &)> TheEvent;
};
class Observer : public std::enable_shared_from_this<Observer>
{
public:
void Attach(std::shared_ptr<Observed> const & observed)
{
observed->TheEvent.Attach(&Observer::OnEvent, shared_from_this());
}
void OnEvent(int & value)
{
assert(value == 10);
value = 1;
}
};
int main(void)
{
auto observed = std::make_shared<Observed>();
auto observer1 = std::make_shared<Observer>();
observer1->Attach(observed);
observed->Fire();
return 0;
}

Event::operator() takes arguments by value. Rewrite it as follows:
template<typename... Args>
void operator()(Args&&... args)
{
for (auto const & listener : Listeners)
{
if (auto locked = std::get<0>(listener).lock())
std::get<1>(listener)(std::forward<Args>(args)...);
}
}

Related

Defer/cancel execution of functions and analyze their arguments

I'm trying to write external draw call optimization, and for that I need to collect hooked calls, store their arguments to analyze them later on.
I've been able to make deferred calls, and somewhat readable arguments, stored in tuple, but I need to read arguments from base class and after thorough googling I can't find anything applicable.
I'll work with array of IDelegateBase mostly, and it would be very inconvenient to convert them to Delegate<...> with full signature, when I mostly would read just one argument. Therefore, I need virtual templated method in IDelegateBase, which would return n-th argument. But virtual templated methods are impossible, so probably I'd have to have templated method in base class, which would call non-template (boost::any?) virtual method and cast it's result, I suppose. But, anyway, I can't get n-th element from tuple via runtime variable.
#include <functional>
#include <iostream>
class IDelegateBase
{
public:
virtual void invoke() { }
};
template <typename T, typename... Args>
class Delegate : public IDelegateBase
{
private:
void (*_f)(Args...);
std::tuple<Args...> _args;
public:
Delegate(T& f, Args &...args)
: _f(f), _args(args...) { }
void invoke() final
{
std::apply(_f, _args);
}
};
void a() { std::cout << "a called;\n"; }
void b(int x) { std::cout << "b called with " << x << "\n"; }
void c(int x, float y) { std::cout << "c called with " << x << ", " << y << "\n"; }
int main()
{
IDelegateBase* d = new Delegate(a);
d->invoke();
int i = 42;
d = new Delegate(b, i);
d->invoke();
i = 21;
float f = 0.999;
d = new Delegate(c, i, f);
d->invoke();
// I need something like this:
auto test = d->getArgument<float>(1);
};
Update:
Final solution with kind of type checking: https://godbolt.org/z/xeEWTeosx
You could provide a virtual function returning void* and use it in a template, but type safety goes down the drain: Should you ever get the type wrong, you'll end up with undefined behaviour.
For getting element using an index you can use a recursive helper template that compares with one index per recursive call.
class IDelegateBase
{
public:
virtual void invoke() { }
template<class T>
T const& getArgument(size_t index) const
{
return *static_cast<T const*>(getArgumentHelper(index));
}
protected:
virtual void const* getArgumentHelper(size_t index) const = 0;
};
template <typename T, typename... Args>
class Delegate : public IDelegateBase
{
private:
void (*_f)(Args...);
std::tuple<Args...> _args;
public:
Delegate(T& f, Args &...args)
: _f(f), _args(args...) { }
void invoke() final
{
std::apply(_f, _args);
}
protected:
void const* getArgumentHelper(size_t index) const override
{
return GetHelper<0>(index, _args);
}
private:
template<size_t index>
static void const* GetHelper(size_t i, std::tuple<Args...> const& args)
{
if constexpr (sizeof...(Args) > index)
{
if (index == i)
{
return &std::get<index>(args);
}
else
{
return GetHelper<index + 1>(i, args);
}
}
else
{
throw std::runtime_error("index out of bounds");
}
}
};
The use of if constexpr is needed here, since std::get does not compile if a of tuple index out of bounds is used.

Is there a std::invoke-alternative in C++14?

As stated in an answer to this question, std::invoke handles calling not just of simple functions but also other callable types.
Unfortunately I am currently constrained to C++14 - so does anyone know of a C++14 compatible alternative?
My motivation:
My actual problem is that I am trying to write a simple wrapper for std::thread where I want to wrap the call of the passed function f with info like isRunning, which will be set to true before calling f(); and false afterwards.
One possible way I found, was to pass a member-method bound via std::bind(&Class::method, classInstance) - this however breaks the API, as this is something the user of my Wrapper class would have to do.
In case anyone is interested, here is my code:
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <thread>
class ThreadPeriodic : public std::thread
{
protected:
struct Settings
{
Settings(std::chrono::nanoseconds const periodDuration)
: isRunning(false)
, stopped(false)
, periodDuration(periodDuration)
{
}
volatile std::atomic<bool> isRunning;
std::mutex mutexStop;
std::condition_variable conditionVariableStop;
volatile std::atomic<bool> stopped;
std::chrono::nanoseconds const periodDuration;
};
std::shared_ptr<Settings> settings_;
template< class Function, class... Args >
class WrapperClass_
{
WrapperClass_() = delete;
public:
// https://stackoverflow.com/questions/34731367/how-to-pass-variadic-args-to-a-stdthread
static void wrapperMethod(std::shared_ptr<Settings> settings,
typename std::decay<Function>::type&& f,
typename std::decay<Args>::type&&... args)
{
settings->isRunning = true;
std::chrono::steady_clock::time_point nextPeriod = std::chrono::steady_clock::now();
bool stopped = settings->stopped.load();
while (!stopped)
{
try
{
f(std::forward<Args>(args)...);
}
catch (...)
{
// allthough this should never happen...
settings->isRunning = false;
throw;
}
nextPeriod += settings->periodDuration;
std::unique_lock<std::mutex> lock(settings->mutexStop);
stopped = settings->conditionVariableStop.wait_until(lock, nextPeriod, [settings](){return settings->stopped;});
}
settings->isRunning = false;
}
};
public:
ThreadPeriodic() noexcept
{
}
ThreadPeriodic(ThreadPeriodic && other) noexcept
{
operator=(std::move(other));
}
template< class Function, class... Args >
explicit ThreadPeriodic(std::chrono::nanoseconds const periodDuration, Function&& f, Args&&... args)
: settings_(std::make_shared<Settings>(periodDuration))
{
std::thread::operator=(std::thread(ThreadPeriodic::WrapperClass_<Function, Args...>::wrapperMethod,
settings_,
std::forward<Function>(f),
std::forward<Args>(args)...));
}
template< class Function, class... Args >
explicit ThreadPeriodic(Function&& f, Args&&... args)
: ThreadPeriodic(std::chrono::nanoseconds(0), std::forward<Function>(f), std::forward<Args>(args)...)
{
}
template< class Rep, class Period, class Function, class... Args >
explicit ThreadPeriodic(std::chrono::duration<Rep, Period> const periodDuration, Function&& f, Args&&... args)
: ThreadPeriodic(std::chrono::duration_cast<std::chrono::nanoseconds>(periodDuration), std::forward<Function>(f), std::forward<Args>(args)...)
{
}
ThreadPeriodic( const ThreadPeriodic& ) = delete;
ThreadPeriodic& operator=( ThreadPeriodic&& other ) noexcept
{
std::thread::operator=(std::move(other));
settings_ = std::move(other.settings_);
return *this;
}
bool isRunning() const
{
std::shared_ptr<Settings> settings = settings_;
return static_cast<bool>(settings) ? settings->isRunning.load() : false;
}
bool isStarted() const
{
std::shared_ptr<Settings> settings = settings_;
return static_cast<bool>(settings) && !settings->stopped;
}
bool isStopped() const
{
std::shared_ptr<Settings> settings = settings_;
return static_cast<bool>(settings) ? settings->stopped.load() : true;
}
// If joinNow is false, join() shall be called later on manually, as to ensure
// the thread is actually joined as it should.
void stop(bool const joinNow = true)
{
std::shared_ptr<Settings> settings = settings_;
if (!static_cast<bool>(settings))
{
throw std::logic_error("ThreadPeriodic::stop: this instance does not represent a thread.");
}
else if (settings->stopped)
{
throw std::logic_error("ThreadPeriodic::stop: this instance is already stopped.");
}
else
{
{
std::unique_lock<std::mutex> lock(settings->mutexStop);
settings->stopped = true;
}
settings->conditionVariableStop.notify_all();
if (joinNow && joinable())
{
join();
}
}
}
};
And if anyone wants to test it, here is a basic program:
#include <iostream>
class TestClass
{
public:
explicit TestClass(int const start = 0)
: start(start)
{
}
void printNumber(int const step = 1)
{
static int number = start;
std::cout << number << std::endl;
number += step;
}
int start;
};
int main()
{
TestClass testInstance(0);
// ThreadPeriodic thread(std::chrono::milliseconds(500), &TestClass::printNumber, testInstance, 3);
ThreadPeriodic thread(std::chrono::milliseconds(500), std::bind(&TestClass::printNumber, testInstance, std::placeholders::_1), 3);
std::this_thread::sleep_for(std::chrono::seconds(2));
thread.stop();
return 0;
}

c++11 : generic type push via a std::function<T(const U&)>

I am trying to build a generic push component.
I have a class store<T> which
has a T t; member
has a void push(const T & t) method called by data providers.
When push is called by a provider, I want a value computed by a std::function< T2(const T&)> and all clients (store<T2>) are notified
with that result value of type T2. A store client has first to subscribe to store via a linker<T, T2> object.
template <class data> class store
{
data data_;
std::list< action<data > > m_links;
public:
void push(const data & e)
{
data_ = e;
for(action<data> a : m_links)
a(data_);
}
void subscribe(action<data> d)
{
m_links.push_back(d);
}
};
Linker object :
template < class data1, class data2 > class linker
{
// source where come the push calls
store<data1> & m_source;
// targets to be notified after computation
std::list<store<data2> * > m_targets;
// computation function
std::function< data2(const data1 &)> m_func;
public:
linker(store<data1> & source, std::function< data2(const data1 &)> func)
: m_source(source), m_func(func)
{
m_source.subscribe([this](const data1 & d){this->push(d);});
}
// add a client
void add_target(store<data2> & target)
{
m_targets.push_back(&target);
}
void push(const data1 & e)
{
//compute result
data2 d2 = m_func(e);
// notify all
for(store<data2> * s2 : m_targets)
{
s2->push(d2);
}
}
};
Use case :
int main()
{
// function : just increment an int, return as double
std::function<double(const int &) > f_inc = [](const int& i){ return i+1;};
// function : display the data
std::function<int(const double&) > f_display = [](const double& d){ std::cout << "value=" << d << std::endl ; return 0;};
store<int> source;
store<double> target, target2;
linker<int, double> l(source, f_inc);
l.add_target(target);
l.add_target(target2);
linker<double, int> display(target, f_display);
source.push(1);
return 0;
}
I want to suppress the explicit-ness of the 'linker' object. I did not succeed because I dont know how to handle the fact that when a store client subscribes to a store object, the object can not store a pointeur to store since it does not know the type T2 !
I would like to write something like that:
std::function<double(const int &) > f_inc = [](const int& i){ return i+1;};
store<int> source;
store<double> target;
source.link_to(target, f_inc);
and be able to unsubscribe :
source.unlink(target, f_inc);
or with ids:
id i = source.link_to(target, f_inc);
source.unsubscribe(i);
I am using codeblocks + mingw 4.8.1 under windows xp.
I guess a design pattern exists for this use case ...
ps: I cant use boost.
It seems to me that by explicitness you mean the fact that Linker has template parameters.
I would envision something like:
class Broker {
public:
Broker(): _lastId(0) {}
//
// Notification
//
template <typename T>
void notify(store<T> const& source, T const& event) {
auto const it = _sources.find(&source);
if (it == _sources.end()) { return; }
for (size_t id: it->second) { _targets.find(id)->second->invoke(&event); }
} // notify
//
// Subscription
//
template <typename T, typename U>
size_t subscribe(Store<T> const& source, U&& callback) {
_targets[++_lastId] = std::unique_ptr<Action>(new ActionT<T>(callback));
_sources[&source].insert(_lastId);
return _lastId;
} // subscribe
template <typename T, typename U>
size_t subscribe(Store<T> const& source, U const& callback) {
return this->subscribe(source, U{callback});
} // subscribe
void unsubscribe(size_t id) {
auto const it = _targets.find(id);
if (it == _targets.end()) { return; }
void const* source = it->second->_source;
auto const it2 = _sources.find(source);
assert(it != _sources.end());
it2->second.erase(id);
if (it2->second.empty()) { _sources.erase(it2); }
_targets.erase(it);
} // unsubscribe
template <typename T>
void unsubscribe(store<T> const& source) {
auto const it = _sources.find(&source);
if (it == _sources.end()) { return; }
for (size_t id: it->second) { _targets.erase(id); }
_sources.erase(it);
} // unsubscribe
private:
//
// Action/ActionT<T> perform Type Erasure (here, we erase T)
//
struct Action {
Action(void const* source): _source(source) {}
virtual void invoke(void const*) = 0;
void const* _source;
}; // struct Action
template <typename T>
class ActionT: Action {
public:
ActionT(store<T> const& source, std::function<void(T)> f):
Action(&source),
_callback(std::move(f))
{}
virtual void invoke(void const* event) {
_callback(T(*static_cast<T const*>(event));
}
private:
std::function<void(T)> _callback;
}; // class ActionT
using Targets = std::map<size_t, std::unique_ptr<Action>>;
using Sources = std::map<void const*, std::set<size_t>>;
size_t _lastId;
Targets _targets;
Sources _sources;
}; // class Broker
As you may see, fairly complicated... and the worst of it ? It is still unsafe. Specifically, there are lifetime issues:
if you register a callback that has references to the external world, you must remove it before those references die
it would be cleaner to remove the sources when they disappear (to prevent a leak)
There are some ways to work around it, you might want to look into signal/slots which help implementing this logic without tying it to a specific object.

Is there a standalone implementation of std::function?

I'm working on an embedded system, so code size is an issue. Using the standard library ups my binary size by about 60k, from 40k to 100k. I'd like to use std::function, but I can't justify it for 60k. Is there a standalone implementation that I can use, or something similar? I'm using it to implicitly cast lambdas in member functions with bound variables in c++ 11.
Here is simple implementation of std::function-like class template without inclusion of any headers. You can customize the behavior as you wish(like move/forward, empty call response, etc):
live_demo
// Scroll down for example of usage
namespace bicycle
{
template<typename Result,typename ...Args>
struct abstract_function
{
virtual Result operator()(Args... args)=0;
virtual abstract_function *clone() const =0;
virtual ~abstract_function() = default;
};
template<typename Func,typename Result,typename ...Args>
class concrete_function: public abstract_function<Result,Args...>
{
Func f;
public:
concrete_function(const Func &x)
: f(x)
{}
Result operator()(Args... args) override
{
return f(args...);
}
concrete_function *clone() const override
{
return new concrete_function{f};
}
};
template<typename Func>
struct func_filter
{
typedef Func type;
};
template<typename Result,typename ...Args>
struct func_filter<Result(Args...)>
{
typedef Result (*type)(Args...);
};
template<typename signature>
class function;
template<typename Result,typename ...Args>
class function<Result(Args...)>
{
abstract_function<Result,Args...> *f;
public:
function()
: f(nullptr)
{}
template<typename Func> function(const Func &x)
: f(new concrete_function<typename func_filter<Func>::type,Result,Args...>(x))
{}
function(const function &rhs)
: f(rhs.f ? rhs.f->clone() : nullptr)
{}
function &operator=(const function &rhs)
{
if( (&rhs != this ) && (rhs.f) )
{
auto *temp = rhs.f->clone();
delete f;
f = temp;
}
return *this;
}
template<typename Func> function &operator=(const Func &x)
{
auto *temp = new concrete_function<typename func_filter<Func>::type,Result,Args...>(x);
delete f;
f = temp;
return *this;
}
Result operator()(Args... args)
{
if(f)
return (*f)(args...);
else
return Result{};
}
~function()
{
delete f;
}
};
}
// ___________________[ Example of usage ]___________________ //
int func1(double)
{
return 1;
}
struct Functor2
{
int operator()(double)
{
return 2;
}
};
double func3(bool,int)
{
return 3.0;
}
struct Functor4
{
double operator()(bool,int)
{
return 4.0;
}
};
int main()
{
int res = 10;
{
bicycle::function<int(double)> f{func1};
res -= f(1.0);
f = Functor2{};
res -= f(2.0);
}
{
bicycle::function<double(bool,int)> f1;
f1 = func3;
bicycle::function<double(bool,int)> f2{f1};
res -= f2(true,1);
f1 = Functor4{};
f2 = f1;
res -= f2(false,2);
}
return res;
}
The 60k came from exception handling being added by the compiler, because exceptions were required for std::function. std::function only throws one exception, "bad_function_call". So I removed the code that threw the exception, now it seg faults if an empty function is called, and I saved myself 60k.

C++0x : Storing any type of std::function in a std::map

I'm trying to store a set of std::function in a map (under GCC 4.5)
I'd like to get 2 kind of things :
storing functions with arguments already passed; then you just have
to call f()
storing functions without arguments; then you have to call
f(...)
I think I achieved the first one with a class Command and a Manager :
class Command
{
std::function<void()> f_;
public:
Command() {}
Command(std::function<void()> f) : f_(f) {}
void execute() { if(f_) f_(); }
};
class CommandManager
{
typedef map<string, Command*> FMap;
public :
void add(string name, Command* cmd)
{
fmap1.insert(pair<string, Command*>(name, cmd));
}
void execute(string name)
{
FMap::const_iterator it = fmap1.find(name);
if(it != fmap1.end())
{
Command* c = it->second;
c->execute();
}
}
private :
FMap fmap1;
};
can be used like this :
class Print{
public:
void print1(string s, string s1){ cout<<"print1 : "<<"s : "<<s<<" s1 : "<<s1<<endl; }
int print2(){ cout<<"print2"<<endl; return 2;}
};
#include <string>
#include <functional>
int main()
{
Print p = Print();
function<void()> f1(bind(&Print::print1, &p, string("test1"), string("test2")));
function<int()> f2(bind(&Print::print2, &p));
CommandManager cmdMgr = CommandManager();
cmdMgr.add("print1", new Command(f1));
cmdMgr.execute("print1");
cmdMgr.add("print2", new Command(f2));
cmdMgr.execute("print2");
return 0;
}
Now I'd like to be able to do this :
int main()
{
Print p = Print();
function<void(string, string)> f1(bind(&Print::print1, &p, placeholders::_1, placeholders::_2));
CommandManager cmdMgr = CommandManager();
cmdMgr.add("print1", new Command(f1));
cmdMgr.execute("print1", string("test1"), string("test2"));
return 0;
}
Is there a way, using type-erasure for example ?
You could use dynamic cast to determine the type of the function in the list at runtime.
Please note that I added shared_ptr to remove the memory leak in the original sample. Perhaps you want to throw a exception if the execute method is called with the wrong arguments (if the dynamic_cast yields 0).
Usage:
void x() {}
void y(int ) {}
void main() {
CommandManager m;
m.add("print", Command<>(x));
m.add("print1", Command<int>(y));
m.execute("print");
m.execute("print1", 1);
}
Code (with variadic template support for example gcc-4.5):
#include <functional>
#include <map>
#include <string>
#include <memory>
using namespace std;
class BaseCommand
{
public:
virtual ~BaseCommand() {}
};
template <class... ArgTypes>
class Command : public BaseCommand
{
typedef std::function<void(ArgTypes...)> FuncType;
FuncType f_;
public:
Command() {}
Command(FuncType f) : f_(f) {}
void operator()(ArgTypes... args) { if(f_) f_(args...); }
};
class CommandManager
{
typedef shared_ptr<BaseCommand> BaseCommandPtr;
typedef map<string, BaseCommandPtr> FMap;
public :
template <class T>
void add(string name, const T& cmd)
{
fmap1.insert(pair<string, BaseCommandPtr>(name, BaseCommandPtr(new T(cmd))));
}
template <class... ArgTypes>
void execute(string name, ArgTypes... args)
{
typedef Command<ArgTypes...> CommandType;
FMap::const_iterator it = fmap1.find(name);
if(it != fmap1.end())
{
CommandType* c = dynamic_cast<CommandType*>(it->second.get());
if(c)
{
(*c)(args...);
}
}
}
private :
FMap fmap1;
};
without variadic template support (example VS2010):
#include <functional>
#include <map>
#include <string>
#include <memory>
using namespace std;
class Ignored;
class BaseCommand
{
public:
virtual ~BaseCommand() = 0 {};
};
template <class A1 = Ignored>
class Command : public BaseCommand
{
typedef std::function<void(A1)> FuncType;
FuncType f_;
public:
Command() {}
Command(FuncType f) : f_(f) {}
void operator()(const A1& a1) { if(f_) f_(a1); }
};
template <>
class Command<Ignored> : public BaseCommand
{
typedef std::function<void()> FuncType;
FuncType f_;
public:
Command() {}
Command(FuncType f) : f_(f) {}
void operator()() { if(f_) f_(); }
};
class CommandManager
{
typedef shared_ptr<BaseCommand> BaseCommandPtr;
typedef map<string, BaseCommandPtr> FMap;
public :
template <class T>
void add(string name, const T& cmd)
{
fmap1.insert(pair<string, BaseCommandPtr>(name, BaseCommandPtr(new T(cmd))));
}
template <class A1>
void execute(string name, const A1& a1)
{
typedef Command<A1> CommandType;
FMap::const_iterator it = fmap1.find(name);
if(it != fmap1.end())
{
CommandType* c = dynamic_cast<CommandType*>(it->second.get());
if(c)
{
(*c)(a1);
}
}
}
void execute(string name)
{
typedef Command<> CommandType;
FMap::const_iterator it = fmap1.find(name);
if(it != fmap1.end())
{
CommandType* c = dynamic_cast<CommandType*>(it->second.get());
if(c)
{
(*c)();
}
}
}
private :
FMap fmap1;
};
What you are trying to do is not possible without some serious runtime work and the associated cost. The simplest solution would of course to just store a boost::any (any_function never made it into boost) inside your map and do the necessary casts (or add some runtime data that tells you which cast to make), although you should avoid that at any cost and go with fixed arguments or no arguments.
Your users can then modify their functions using bind to match the signature you require.
Edit: In your current scheme I see no reason for CommandManager to store Command* in the map.
Edit2: Also you drop the return type. This could be OK for your use-case but makes this a lot less generic.
Edit3: I worked out some working example of your code using any. I feel that there is some flaw and I really don't see what this should achieve but here it goes:
#include <iostream>
#include <string>
#include <map>
#include <functional>
#include <boost/any.hpp>
class AnyCaller
{
std::map<std::string, boost::any> calls;
public:
AnyCaller() {}
void add(const std::string& name, const boost::any& fun) {
calls[name] = fun;
}
// we always use the throwing version of any_cast
// icbb by error checking
// no arg version
template<typename Ret>
Ret call(const std::string& s) {
const boost::any& a = calls[s];
return boost::any_cast< std::function<Ret(void)> >(a)();
}
// this should be a variadic template to be actually usable
template<typename Ret, typename T>
Ret call(const std::string& s, T&& arg) {
// we have to assume that our users know what we are actually returning here
const boost::any& a = calls[s];
return boost::any_cast< std::function<Ret(T)> >(a)(std::forward<T>(arg));
}
virtual ~AnyCaller() {}
};
int foo() { std::cout << "foo" << std::endl; return 1; }
double foo2(int i) { std::cout << "foo2" << std::endl; return double(i); }
int main()
{
AnyCaller c;
c.add("foo", std::function<int(void)>(foo));
c.add("foo2", std::function<double(int)>(foo2));
c.call<int>("foo");
c.call<double, int>("foo2", 1);
// this should throw
c.call<double, int>("foo", 1);
return 0;
}
As for the example using a fixed signature. Just think of what would be the most natural representation of a function you are going to store (looking at your Command example I'd assume it is std::function<void(void)>. Store functions of this type and whenever one your users tries to use it, he has to bind whatever function he wants to use, so it matches this signature.
Your Command class constructor needs a function<void()>. You are trying to feed it a function<void(string,string)>. This is not going to typecheck.
If you need functions that accept variable arguments (like printf), you will need function<> and execute() that accept variable arguments. You need to know how to work with that (in particular, you need a fixed first argument). You are then responsible for type safety, much like with printf.
If you just need a variable number of string arguments, use functions that accept e.g. vectors of strings.
All this has nothing to do whatsoever with std::map. Whatever you can store in a plain old variable, you can store in std::map too.