Can't add perfect forwarding to wrapper function

妖精的绣舞 提交于 2019-12-04 12:23:00

You have the dots in the wrong place on the return statement. You want:

return fn(std::forward<Args>(args)...);

This will expand to:

return fn(std::forward<T1>(t1), std::forward<T1>(t2), ...);

What you wrote would have expanded to:

return fn(std::forward<T1,T2,...>(t1, t2, t3)); 

The trick is that everytime you see "...", think "it will replicate the thing behind it". This can get tricky because there are all sorts of ways to construct the "thing behind it", including being able to do a cross-product and the like.

#include<utility>
template<typename Fn, Fn fn, typename... Args>
auto wrapper(Args&&... args)->decltype(fn(std::forward<Args>(args)...)){
//                             vvvvvvvvvv---- Oopsie ! ----^^^^^^^^^^
    return fn(std::forward<Args>(args)...);
}

On each line, the single ellipsis will expand both Args and args in parallel. You will end up with :

std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), ...

... rather than the incorrect :

std::forward<Arg1, Arg2, ...>(arg1, arg2, ....)

You might also be interested in std::result_of to trim that declatation a bit :

#include<utility>
template<typename Fn, Fn fn, typename... Args>
auto wrapper(Args&&... args) -> std::result_of<Fn(Args...)>::type {
    return fn(std::forward<Args>(args)...);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!