It is not entirely clear what you hope to achieve with respect to the rvalue reference element. It just doesn't look right. You should avoid storing the link. You can still use things like std :: ref and std :: cref if you want the function object to store the reference object (just like std :: bind behaves).
The problem you are facing is that she is not allowed to initialize the rvalue reference with the lvalue of the target type. But you are trying to do this because the constructor parameter "arg" is the named parameter rvalue, which makes this expression lvalue in the list of initializers. You probably used an old version of GCC to compile this code. Newer versions will also complain about this.
You can save some problems by relying on std :: bind:
template<class FuncType> class F : public B { public: explicit F(FuncType func) : f(std::forward<FuncType>(func)) {} void execute() { f(); } private: FuncType f; }; .... auto fun = std::bind(myFunction,text2.c_str()); B* ptr = new F<decltype(fun)>(fun);
If you really want to deal with parameter binding, you should do it like this:
template<class FuncType, class ParamType> class F : public B { public: F(FuncType func, ParamType para) : f(std::forward<FuncType>(func)) , p(std::forward<ParamType>(para)) void execute() { f(p); } private: FuncType f; ParamType p; };
Keep in mind that the type of the parameter T && where T can be inferred is of particular importance. This is the catch-all parameter. The output of the template argument will make T a reference to the lvalue (and T & &, as well as the standard discard rules) if the argument was an lvalue. So, if you always want the parameter to be stored as a copy, you need to write
template<class FuncType, class ArgType> B * registerFunc(FuncType func, ArgType && arg) { typedef typename std::decay<ArgType>::type datype; return new F<FuncType,datype>(func, std::forward<ArgType>(arg)); }
I would prefer a registerFunc function like this. It copies the function object and the default object object. Overriding this can be done via std :: ref and std :: cref:
registerFunc(some_func,std::cref(some_obj));