The code I'm looking for is like following.
bool Func1(int Arg1, C++11LambdaFunc Arg2){
if(Arg1 > 0){
return Arg2(Arg1);
}
}
Later I'll be using this code.
Func1(12, [](int D) -> bool { ... } );
Basic version, for use in a header file:
template<typename Lambda>
bool Func1(int Arg1, Lambda Arg2){ // or Lambda&&, which is usually better
if(Arg1 > 0){
return Arg2(Arg1);
} else {
return false; // remember, all control paths must return a value
}
}
More complex version, if you want to split your interface from your implementation (it has run time costs):
bool Func1(int Arg1, std::function<bool(int)> Arg2){
if(Arg1 > 0){
return Arg2(Arg1);
} else {
return false; // remember, all control paths must return a value
}
}
std::function uses type erasure to create a custom-created wrapper around your lambda, and then exposes a non-virtual interface that uses the pImpl pattern to forward it to the custom-created wrapper.1
Or, in less technical terms, std::function<bool(int)> is a class that can wrap nearly anything that you can call like a function, passing one parameter that is compatible with passing an int, and it returns something that is compatible with returning a bool.
A call through a std::function has a run time cost roughly equal to a virtual function call (caused by the above type erasure), and when you create it it has to copy the state of the function object (aka functor) passed in (which can be cheap -- stateless lambdas, or lambdas capturing arguments by reference -- or expensive in some other cases) and store it (typically on the free store or heap, which has a cost), while the pure-template versions can be "inlined" at the point of call (ie, can not only cost less than a function call, the compiler can even optimize over the function call and return boundaries!)
If you want to split interface/implementation without all of the runtime costs of std::function, you can roll your own function_ref (in c++17, because that cuts down on some boilerplate):
template<class Sig>
struct function_ref;
template<class R, class...Args>
struct function_ref<R(Args...)> {
R operator()(Args...args) const {
return pf(state, std::forward<Args>(args)...);
}
function_ref()=default;
function_ref(function_ref const&)=default;
function_ref& operator=(function_ref const&)=default;
explicit operator bool()const{ return pf!=nullptr; }
// this overload reduces indirection by 1 step
// and allows function_ref<Sig> to resolve overloads
// on an overload set sometimes.
function_ref( R(*f)(Args...) ):
pf([](State const& state, Args&&...args)->R{
return reinterpret_cast<R(*)(Args...)>(state.pfunstate)(std::forward<Args>(args)...);
})
{
state.pfunstate = reinterpret_cast<void(*)()>(f);
}
// this grabs anything callable (that isn't this own type)
// and stores a pointer to it to call later.
template<class F>
requires (
std::is_convertible_v<
std::invoke_result_t< std::remove_reference_t<F>, Args... >, R
>
&& !std::is_same_v< std::decay_t<F>, function_ref >
)
function_ref( F&& f ):
pf([](State const& state, Args&&...args)->R{
return (*(std::remove_reference_t<F>*)state.pstate)(std::forward<Args>(args)...);
})
{
state.pstate = std::addressof(f);
}
private:
union State {
void* pstate = nullptr;
void(*pfunstate)();
};
State state;
R(*pf)(State const&, Args&&...) = nullptr;
};
// a deduction guide permitting function_ref{foo} to work
// if foo is a non-overloaded function name.
template<class R, class...Args>
function_ref( R(*)(Args...) )->function_ref<R(Args...)>;
Live example.
This removes the need to ever do any allocation from std::function by removing ownership semantics from it and just type-erasing calling.
A fancy version of the first example that also handles some corner cases a tad better: (also must be implemented within a header file, or in the same translation unit as it is used)
template<typename Lambda>
bool Func1(int Arg1, Lambda&& Arg2){
if(Arg1 > 0){
return std::forward<Lambda>(Arg2)(Arg1);
} else {
return false; // remember, all control paths must return a value
}
}
which uses a technique known as "perfect forwarding". For some functors, this generates slightly different behavior than #1 (and usually more correct behavior).
Most of the improvement comes form the use of && in the argument list: this means that a reference to the functor is passed in (instead of a copy), saving some costs, and allows both a const or non-const functor to be passed in.
The std::forward<Lambda>(...) change would only cause a change in behavior if someone used a relatively new C++ feature that allows methods (including operator()) to override on the rvalue/lvalue status of the this pointer. In theory, this could be useful, but the number of functors I've seen that actually override based on the rvalue status of this is 0. When I'm writing serious library code (tm) I go to this bother, but rarely otherwise.
There is one more possible thing to consider. Suppose you want to take either a function that returns bool, or a function that returns void, and if the function returns void you want to treat it as if it returned true. As an example, you are taking a function that is being called when iterating over some collection, and you want to optionally support early halting. The function returns false when it wants to stop prematurely, and true or void otherwise.
Or, in a more general case, if you have multiple overrides of a function, one of which takes a function and others take some other type at the same location.
This is possible, which is as far as I'm going to get into here (either with a smart adapter, or via SFINAE techniques). However, you are probably better off just creating two different named functions, because the techniques required are way too heavy weight.
1 Technically std::function could use magic fairy dust to do what it does, as its behavior is described by the standard, and not its implementation. I'm describing a simple implementation that approximates the behavior of the std::function implementation I have interacted with.
First solution:
You can make your Func1() function a function template:
template<typename T>
bool Func1(int Arg1, T&& Arg2){
if(Arg1 > 0){
return Arg2(Arg1);
}
return false; // <== DO NOT FORGET A return STATEMENT IN A VALUE-RETURNING
// FUNCTION, OR YOU WILL GET UNDEFINED BEHAVIOR IF FLOWING
// OFF THE END OF THE FUNCTION WITHOUT RETURNING ANYTHING
}
You could then invoke it as you desire:
int main()
{
Func1(12, [](int D) -> bool { return D < 0; } );
}
Second solution:
If you do not want to use templates, an alternative (that would bring some run-time overhead) is to use std::function:
#include <functional>
bool Func1(int Arg1, std::function<bool(int)> Arg2){
if(Arg1 > 0){
return Arg2(Arg1);
}
return false;
}
Once again, this would allow you to call Func1() the way you desire:
int main()
{
Func1(12, [](int D) -> bool { return D < 0; } );
}
For those whose tastes are more traditional, note that non-capturing lambdas can convert to function pointers. So you can write your function above as:
bool Func1(int Arg1, bool (*Arg2)(int)) { ... }
And it will work correctly for both traditional functions and lambdas.
Related
I recently wrote about the function of class member function callbacks. I need to save the callback object and function pointer, then call the function pointer and fill in the appropriate parameters where the callback is needed.
I started out as a form of typedef void (AAA::*Function)(int a, int b);, but when I need to support different parameter lists of member function, I obviously need a dynamic way to implement it.
class AAA
{
public:
int add(int a, int b)
{
return (a + b);
}
};
class BBB
{
public:
void setValue(std::string value)
{
this->value = value;
}
private:
std::string value;
};
class CCC
{
public:
void bind(??? p) // Binding objects and callback functions.
{
this->p = p;
}
template <class... Args>
auto callback(Args&&... args) // Autofill parameter list.
{
return this->p(std::forward<Args>(args)...);
}
private:
??? p; // How is this function pointer implemented?
};
int main()
{
AAA aaa;
BBB bbb;
CCC ccc;
ccc.bind(???(aaa, &AAA::add));
int number = ccc.callback(5, 6);
ccc.bind(???(bbb, &BBB::setValue));
ccc.callback("Hello");
system("pause");
return 0;
}
I don't know how can I implement the function pointer "???".
You basically are asking to have fully dynamicly typed and checked function calls.
To have fully dynamic function calls, you basically have to throw out the C++ function call system.
This is a bad idea, but I'll tell you how to do it.
A dynamicly callable object looks roughly like this:
using dynamic_function = std::function< std::any( std::vector<std::any> ) >
where use use
struct nothing_t {};
when we want to return void.
Then you write machinery that takes an object and a specific signature, and wraps it up.
template<class R, class...Args, class F>
struct dynamic_function_maker {
template<std::size_t...Is>
dynamic_function operator()(std::index_sequence<Is...>, F&& f)const {
return [f=std::forward<F>(f)](std::vector<std::any> args)->std::any {
if (sizeof...(Is) != args.size())
throw std::invalid_argument("Wrong number of arguments");
if constexpr( std::is_same< std::invoke_result_t<F const&, Args... >, void >{} )
{
f( std::any_cast<Args>(args[Is])... );
return nothing_t{};
}
else
{
return f( std::any_cast<Args>(args[Is])... );
}
};
}
dynamic_function operator()(F&& f)const {
return (*this)(std::make_index_sequence<sizeof...(Args)>{}, std::forward<F>(f));
}
};
template<class R, class...Args, class F>
dynamic_function make_dynamic_function(F f){
return dynamic_function_maker<R,Args...,F>{}(std::forward<F>(f));
}
next you'll want to deduce signatures of function pointers and the like:
template<class R, class...Args>
dynamic_function make_dynamic_function(R(*f)(Args...)){
return dynamic_function_maker<R,Args...,F>{}(std::forward<F>(f));
}
template<class Tclass R, class...Args>
dynamic_function make_dynamic_function(T* t, R(T::*f)(Args...)){
return dynamic_function_maker<R,Args...,F>{}(
[t,f](auto&&...args)->decltype(auto){return (t->*f)(decltype(args)(args)...);}
);
}
then after fixing typos above you should be able to solve your original problem.
Again, as someone who can actually write and understand the above code, I strongly advise you not to use it. It is fragile and dangerous.
There is almost never a good reason to store callbacks in places where you don't know what the arguments you are going to call it with.
There should be a different type and instance of CCC for each set of arguments you want to call it with. 99/100 times when people ask this question, they are asking the wrong question.
C++ is a type-safe language. This means that you cannot do exactly what you've outlined in your question. A pointer to a function that takes specific parameters is a different type from a pointer to a function that takes different parameters. This is fundamental to C++.
std::bind can be use to type-erase different types to the same type, but you get a single type at the end, that can be called only with a matching set of parameters (if any). It is not possible to invoke the "underlying" bound function, with its real parameters. That's because the whole purpose of std::bind is to make them disappear, and inaccessible. That's what std::bind is for.
You only have a limited set options to make this work while staying with the bounds and constraints of C++'s type-safety.
Make use of a void *, in some fashion. Actually, don't. Don't do that. That will just cause more problems, and headache.
Have a separate list and classes of callbacks, one list for each set of callbacks that take a specific set of parameters. You must know, at the point of invoking a callback, what parameters you intend to pass. So, just get your callback from the appropriate list.
Make use of std::variant. The type-safe std::variant is C++17 only (but boost has a similar template that's mostly equivalent, and available with older C++ revisions). All your callbacks take a single std::variant parameter, a variant of every possible set of parameters (designated as a std::tuple of them, or some class/struct instance). Each callback will have to decide what to do if it receives a std::variant containing the wrong parameter value.
Alternatively, the std::variant can be a variant of different std::function types, thus shifting the responsibility of type-checking to the caller, instead of each callback.
The bottom line is that C++ is fundamentally a type-safe language; and this is precisely one of the reasons why one would choose to use C++ instead of a different language that does not have the same kind of type-safety.
But being a type-safe language, that means that you have certain limitations when it comes to juggling different types together. Specifically: you can't. Everything in C++ is always, and must be, a single type.
I am trying to build a chain of callable objects that can be later executed asynchronously. I wanted to try out the following approach: build a "nested" structure of nodes (by moving each node into its "parent") resulting in an object that stores all the computations and can be start the chain on demand.
This is what I had in mind:
template <typename TParent, typename TF>
struct node
{
TParent _parent;
TF _f;
node(TParent&& parent, TF&& f)
: _parent{std::move(parent)}, _f{std::move(f)}
{
}
template <typename TFContinuation>
auto then(TFContinuation&& f_continuation)
{
using this_type = node<TParent, TF>;
return node<this_type, std::decay_t<TFContinuation>>
{std::move(*this), std::move(f_continuation)};
// ^^^^^^^^^^^^^^^^
// ...safe?
}
};
The code above would allow the user to write chains like the following one:
int main()
{
node n{some_root_callable, []{/*...*/}};
n.then([]{/*...*/})
.then([]{/*...*/})
.then([]{/*...*/})
.then([]{/*...*/});
}
(The real implementation would support more useful abstraction such as when_all(...) or when_any(...).)
Wandbox example.
Assuming that TParent, TF, and TFContinuation are movable callable objects, is it safe (i.e. well-defined) to call std::move(*this) during the invocation of node::then?
You can do that and it's safe. It will only leaves members in an undefined but valid state in most cases. With that said, it is safe to move this, as long as you don't try to use its members again. But with standard library types and most user defined types, this won't even be a problem.
There is one thing that I would change. I would only allow call from rvalue this:
template <typename TFContinuation> // v-- notice the && here.
auto then(TFContinuation&& f_continuation) && {
using this_type = node<TParent, TF>;
return node<this_type, std::decay_t<TFContinuation>>{
std::move(*this), std::move(f_continuation)
};
}
The great this is you can even overload it when it's not an rvalue:
template <typename TFContinuation>
auto then(TFContinuation&& f_continuation) const & {
using this_type = node<TParent, TF>;
return node<this_type, std::decay_t<TFContinuation>>{
*this, std::move(f_continuation)
};
}
Whether there's a problem in that code depends on what that code does with the reference that it gets. If the called code turns the object into mush, then when it returns, your code has to deal with an object that's been turned into mush. But that's true of any function that you call from a member function, regardless of whether its called with an rvalue reference, a modifiable lvalue reference, a pointer, or any other mechanism you might want to imagine.
What is the best way of passing a callback function parameter in C++?
I thought of simply using templates, like this:
template <typename Function>
void DoSomething(Function callback)
This is the way used e.g. in std::sort for the comparison function object.
What about passing using &&? E.g.:
template <typename Function>
void DoSomething(Function&& callback)
What are the pros and cons of those two methods, and why does the STL uses the former e.g. in std::sort?
The
template <typename Function>
void DoSomething(Function&& callback)
… which uses a forwarding reference to pass by reference, is IMHO superior for the case where the function just uses the callback. Because a functor object, although usually small, can be arbitrarily large. Passing it by value then incurs some needless overhead.
The formal argument can end up as T&, T const& or T&& depending on the actual argument.
On the other hand, passing a simple function pointer by reference involves an extra needless indirection, which in principle could mean some slight overhead.
If in doubt whether this is significant for a given compiler, system and application, then measure.
Regarding
” why does the STL uses the former [passing by value] e.g. in std::sort?
… it's worth noting that std::sort has been there since C++98, well before forwarding references were introduced in C++11, so it could not have that signature originally.
Possibly there just has not been sufficient incentive to improve this. After all, one should generally not fix that which works. Still, extra oveloads with an “execution policy” argument are introduced in C++17.
Since this concerns a possible C++11 change, it's not covered by the usual source for rationales, namely Bjarne Stroustrup's “The design and evolution of C++”., and I do not know of any conclusive answer.
Using the template<class F> void call( F ) style, you can still get back "pass by reference". Simply do call( std::ref( your callback ) ). std::ref overrides operator() and forwards it to the contained object.
Simularly, with template<class F> void call( F&& ) style, you can write:
template<class T>
std::decay_t<T> copy( T&& t ) { return std::forward<T>(t); }
which explicitly copies something, and force call to use a local copy of f by:
call( copy(f) );
so the two styles mainly differ in how they behave by default.
Since this is C++11 (or higher): <functional> and std::function are your best friends here.
#include <iostream>
#include <functional>
#include <string>
void DoSomething(std::function<void()> callback) {
callback();
}
void PrintSomething() {
std::cout << "Hello!" << std::endl;
}
int main()
{
DoSomething(PrintSomething);
DoSomething([]() { std::cout << "Hello again!" << std::endl; });
}
In my opinion, using the && would be the superior way, basically because it avoids copy constructing the functor when the argument is an lvalue. In case of a lambda, this means avoiding to copy construct all captured values. In case of an std::function you also have an additional heap allocation unless small object optimizations are used.
But there are some cases when it could be a good thing to have a copy of the functor. One example is when using a generator function object like this:
#include <functional>
#include <cstdio>
template <typename F>
void func(F f) {
for (int i = 0; i < 5; i++) {
printf("Got %d\n", (int)f());
}
}
int main() {
auto generator0 = [v = 0] () mutable { return v++; };
auto generator1 = generator0; generator1();
printf("Printing 0 to 4:\n");
func(generator0);
printf("Printing 0 to 4 again:\n");
func(generator0);
printf("Printing 1 to 5:\n");
func(generator1);
}
If we used F&& instead, the second group of prints would print values 5 to 9 instead of 0 to 4. I guess it's up to the application/library what behaviour is preferred.
When using function pointers, we could also end up in a situation when an extra level of indirection must be used in the invoke2 function:
template <typename F>
void invoke1(F f) {
f();
}
template <typename F>
void invoke2(F&& f) {
f();
}
void fun();
void run() {
void (*ptr)() = fun;
void (&ref)() = fun;
invoke1(fun); // calls invoke1<void (*)()>(void (*)())
invoke1(&fun);// calls invoke1<void (*)()>(void (*)())
invoke1(ptr); // calls invoke1<void (*)()>(void (*)())
invoke1(ref); // calls invoke1<void (*)()>(void (*)())
invoke2(fun); // calls invoke2<void (&)()>(void (&)())
invoke2(&fun);// calls invoke2<void (*)()>(void (*&&)())
invoke2(ptr); // calls invoke2<void (*&)()>(void (*&)())
invoke2(ref); // calls invoke2<void (&)()>(void (&)())
}
The statement invoke2(&fun); puts the address to the function on the stack, then sends the reference (i.e. an address) to this temporary stack slot to the invoke2 function. The invoke2 function must then use an extra memory lookup to read the reference on the stack before it can use it. The extra indirection applies for invoke2(ptr) too. In all other cases, the address to the function is sent directly to the invoke1/invoke2 function and does not need any extra indirection.
This example shows one interesting difference between a function reference and a function pointer.
Of course, compiler optimisation such as inlining could easily get rid of this extra indirection.
Fairly simple question:
I have a class that uses a (variable) heuristic function to perform a certain algorithm. This heuristic function should ideally be fed to the class constructor as some sort of pointer and implement the following declaration:
int heuristic_Function(GridLocation a, GridLocation b);
What is the best way to accomplish this? Ideally I would like to avoid additional classes and keep the code fairly self-contained (and yes, I am aware of things like delegates and the strategy pattern).
(This has probably been asked hundreds of times already but in different terms)
Well, as you said, you could store a function pointer:
struct Algo
{
using HeurFn = int(GridLocation, GridLocation);
Algo(HeurFn * heuristic) : heuristic_(heuristic) {}
void Run()
{
// use "heuristic_(a, b)"
}
HeurFn * heuristic_;
};
Then instantiate it:
extern int my_fn(GridLocation, GridLocation);
Algo algo(my_fn);
algo.Run();
An alternative would be to pass the function directly to Run, in which case you could make Run a template and perhaps allow for inlining of the actual heuristic code, but you explicitly asked for the heuristic to be configured via the constructor.
Instead of old C function pointer, I would recommend std::function.
So you could write it like this
#include <functional>
struct algorithm{
algorithm (std::function<int(GridLocation, GridLocation)> heuristic_function) :
heuristic(heuristic_function) {}
int do_something (GridLocation a, GridLocation b){
return heuristic(a,b);
}
private:
std::function<int(GridLocation, GridLocation)> heuristic;
}
Advantages are the better readable syntax, and that the caller can use std::bind expressions.
Or you could just take the heuristic as a template, but then you would to either make your algorithm to just a function or write the type to every new instance. See https://stackoverflow.com/a/2156899/3537677
Things get really simple if only the method that does the computations needs the function, and you can forgo storing the function in the class itself. You can then parametrize the method on the type of the passed function, and you get full flexibility:
struct Calculate {
template <typename F> int run(F && f) {
return f(1, 2);
}
};
int f1(int, int) { return 0; }
struct F2 {
int operator()(int, int) { return 0; }
};
int main() {
Calculate calc;
// pass a C function pointer
calc.run(f1);
// pass a C++98 functor
calc.run(F2());
// pass a C++11 stateless lambda
calc.run(+[](int a, int b) -> int { return a-b; });
// pass a C++11 stateful lambda
int k = 8;
calc.run([k](int a, int b) -> int { return a*b+k; });
}
You don't need to manually spell out any types, and you can pass function-like objects that can be stateful.
The power of C++11 comes from the && syntax. There's more to it than meets the eye. In run's parameter, F is a deduced type, and && is a universal reference. That means that, depending on the context, it acts either as an lvalue-reference we know from C++98, or as an rvalue-reference.
The + operator applied to the lambda stresses that it is in fact stateless. Its uses forces a conversion from the abstract lambda type to a C function pointer. The type of the +[](int,int)->int {...} expression is int(*)(int,int). The use of the + operator is not necessary, I've only used it to underline the statelessness.
I want to implement a "Task" class, which can store a function pointer along with some arguments to pass to it. like std::bind(). and I have some question about how to store the arguments.
class BaseTask {
public:
virtual ~BaseTask() {}
virtual void run() = 0;
};
template<typename ... MTArg>
class Task : public BaseTask {
public:
typedef void (*RawFunction)(MTArg...);
Task(RawFunction rawFunction, MTArg&& ... args) : // Q1: MTArg&& ... args
rawFunction(rawFunction),
args(std::make_tuple(std::forward<MTArg>(args)...)) {} // Q2: std::make_tuple(std::forward<MTArg>(args)...)
virtual void run() {
callFunction(GenIndexSequence<sizeof...(MTArg)>()); // struct GenIndexSequence<count> : IndexSequence<0, ..., count-1>
}
private:
template<unsigned int... argIndexs>
inline void callFunction() {
rawFunction(std::forward<MTArg>(std::get<argIndexs>(args))...);
}
private:
RawFunction rawFunction;
std::tuple<MTArg...> args; // Q3: std::tuple<MTArg...>
};
Q1: is && after MTArg necessary
Q2: is this way correct to init args
Q3: is type of args correct, do I need:
std::tuple<special_decay_t<MTArg>...>
according to this: http://en.cppreference.com/w/cpp/utility/tuple/make_tuple
// end of questions
I want Task can be used in this way:
void fun(int i, const int& j) {}
BaseTask* createTask1() {
return new Task<int, const int&>(&fun, 1, 2); // "2" must not be disposed at the time of task.run(), so inside Task "2" should be store as "int", not "const int&"
}
BaseTask* createTask2(const int& i, const int& j) {
return new Task<int, const int&>(&fun, i, j); // "j" must not be disposed at the time of task.run(), so inside Task "j" should be store as "int", not "const int&"
}
void test(){
createTask1()->run();
createTask2(1, 2)->run();
}
task will only be run no more then once, that is zero or one times.
You aren't allowed to use std::tuple::special_decay_t even if it exists: it is an implementation detail. That code on cppreference exists for exposition only: it works "as if" that type exists. If your implementation uses that code, that is an implementation detail that different compilers will not have, and the next iteration of your compiler is free to change/make private/rename/etc.
As exposition, it explains what you need to write if you want to repeat the special decay process of std::make_tuple and a few other C++11 interfaces.
As a first step, I'll keep your overall design, and repair it a touch. Then I'll point out an alternative.
MTArg... are the parameters of the function:
template<typename ... MTArg>
struct Task {
typedef void (*RawFunction)(MTArg...);
Here we want to forward some set of arguments into a tuple, but the arguments need not match MTArg -- they just have to be convertible:
template<typename ... Args>
explicit Task(RawFunction rawFunction, Args&&... args)
rawFunction(rawFunction),
args(std::make_tuple(std::forward<Args>(args)...)) {}
which the above checks. Note I made it explicit, as if Args... is empty, we don't want this to be a converting constructor.
void run() {
callFunction(GenIndexSequence<sizeof...(MTArg)>());
}
private:
template<unsigned int... argIndexs>
inline void callFunction() {
rawFunction(std::forward<MTArg>(std::get<argIndexs>(args))...);
}
RawFunction rawFunction;
std::tuple<MTArg...> args;
};
and then we write a make_task function:
template<typename ... MTArg, typename... Args>
Task<MTArg...> make_task( void(*raw)(MTArg...), Args...&& args ) {
return { raw, std::forward<Args>(args)... };
}
which looks something like that. Note that we deduce MTArg... from the function pointer, and Args... from the arguments.
Just because our function takes foo by value, does not mean we should make copies of it, or store an rvalue reference to it, or what have you.
Now, the above disagrees with how std::function and std::thread work, which is where special_decay_t comes in.
Usually when you store arguments to a function, you want to store actual copies, not references to possibly local variables or temporary variables that may go away. And if your function takes arguments by lvalue non-const reference, you want to take extra care at the call site that you aren't binding it to stack variables.
That is where reference_wrapper comes in and the special_decay_t bit: deduced arguments are decayed into literals, which have conventional lifetimes. Types packaged into std::reference_wrapper are turned into references, which lets you pass references through the interface.
I'd be tempted to duplicate the C++11 pattern, but force creators of a Task to explicitly reference_wrapper all types that are supposed to be passed by reference into the raw function.
But I am unsure, and the code to do that gets a touch messy.
Q1: is && after MTArg necessary
Task(RawFunction rawFunction, MTArg&& ... args) : // Q1: MTArg&& ... args
No, it is not necessary, since it is a concrete function (constructor in this case). It would matter if it was a template function, then args would be of universal reference type.
For the same reason, you do not need to use std::foward.
Q3: is type of args correct, do I need:
std::tuple<special_decay_t<MTArg>...>
Yes, because types should not be rvalues, if you want to store them in a tupple.