Reputation: 2244
I created a small function wrapper example. I want to make the wrapper consider whether or not the function called is using (const) references, meaning the output will be 4/5 and not 4/4, but I don't want to enforce reference usage if the wrapped function does not use them.
#include <iostream>
#include <string>
struct a {
static void run(int cref) {
cref = 5;
};
};
struct b {
static void run(int &cref) {
cref = 5;
};
};
template <class FTor>
struct foo {
template <class ... Args>
static void wrapper(Args ... args) {
FTor::run(args ...);
}
};
int main()
{
int bar = 4;
foo<a>::wrapper(bar);
std::cout << bar;
foo<b>::wrapper(bar);
std::cout << bar;
}
Upvotes: 2
Views: 141
Reputation: 5710
This is an attempt to answer what is possibly a misinterpretation of mine regarding the OP's request, as simple perfect forwarding solves the scenario described without resorting to the wrapped function arguments' types deduction.
Original answer: At least for the restricted use case such as you're presenting, you can use a small type trait struct to infer the type of single argument being passed to wrapper()
from the type of argument of the functor:
#include <iostream>
#include <string>
struct a {
static void run(int cref) {
cref = 5;
};
};
struct b {
static void run(int &cref) {
cref = 5;
};
};
template <typename>
struct ArgType;
template <typename R, typename A>
struct ArgType<R(A)>
{ using type = A; };
template <class FTor>
struct foo {
static void wrapper(typename ArgType<decltype(FTor::run)>::type args) {
FTor::run(args);
}
};
int main()
{
int bar = 4;
foo<a>::wrapper(bar);
std::cout << bar;
foo<b>::wrapper(bar);
std::cout << bar;
}
Output:
45
Note this won't support perfect forwarding from within the wrapper, as wrapper()
here is not itself part of a *type deducing context` -- as opposed to your snippet, that deduces but not based on what you want it to deduce. I'll hopefully find the time to add a generalized solution for variadic function template such as in your snippet, perfect forwarding included.
Upvotes: 1
Reputation: 10760
What about just using perfect forwarding?
template <class FTor>
struct foo {
template <class ... Args>
static void wrapper(Args && ... args) {
FTor::run(std::forward<Args>(args) ...);
}
};
That way, whatever ref-qualification the parameter has on input gets passed along to the inner function.
Upvotes: 3