Reputation: 420
I would like to use a function as argument in a variadic template, why does the following not work? How do I make it work?
template<typename F, typename... Args>
F test(F f, const Args&&... args) {
return f(std::forward<Args>(args)...);
}
int simple(int i) {
return i;
}
int main()
{
std::cout << test(simple, 2); // error, 'std::forward': none of the 2 overloads could convert all the argument types
}
Upvotes: 0
Views: 1099
Reputation: 10415
The first problem is the return type. Your test
function returns F
which is a function pointer. Instead change it to auto
to automatically deduce the return type.
The second issue is that std::forward
requires a non-const reference.
You might use trailing return type:
template<typename F, typename... Args>
auto test(F f, Args&&... args) -> decltype(f(std::forward<Args>(args)...)) {
return f(std::forward<Args>(args)...);
}
But decltype(auto)
(C++14 required) is a simpler solution:
template<typename F, typename... Args>
decltype(auto) test(F f, Args&&... args) {
return f(std::forward<Args>(args)...);
}
Upvotes: 0
Reputation: 17483
There are a couple of problems with your code.
First of all, you should use forwarding references, so you need to change const Args&&...
to Args&&...
.
Then, test
does not have to return F
. So it is reasonable to use decltype(auto)
here.
In addition to that, it makes sense to forward f
too.
The fixed version might look like this:
template<typename F, typename... Args>
decltype(auto) test(F&& f, Args&&... args) {
return std::forward<F>(f)(std::forward<Args>(args)...);
}
Upvotes: 3