【问题标题】:Can't add perfect forwarding to wrapper function无法向包装函数添加完美转发
【发布时间】:2014-08-20 14:48:11
【问题描述】:

在回答this question 时,我编写了这个工作代码,包装了传入模板参数的函数:

template<typename Fn, Fn fn, typename... Args>
auto wrapper(Args... args)->decltype(fn(args...)){
    return fn(args...);
}
#define WRAPPER(FUNC) wrapper<decltype(&FUNC), &FUNC>

示例用法(我使用此代码进行测试):

int min(int a, int b){
    return (a<b)?a:b;
}

#include<iostream>
using std::cout;
int main(){
    cout<<WRAPPER(min)(10, 20)<<'\n';
}

两个人告诉我使用完美转发。当我问如何做到这一点时,其中一位重定向了我here。我阅读问题,仔细阅读最佳答案,并将wrapper更改为:

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

它会编译,除非我尝试使用上面的示例代码检查它。 如何修复代码?

http://rextester.com/YUIYI99787

【问题讨论】:

    标签: c++ c++11 wrapper variadic-templates perfect-forwarding


    【解决方案1】:

    您在 return 语句中的点有误。你想要:

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

    这将扩展为:

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

    你写的内容会扩展为:

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

    诀窍在于,每次看到“...”时,都会想“它会复制它背后的东西”。这可能会变得很棘手,因为有各种各样的方法来构建“背后的东西”,包括能够做一个交叉产品等等。

    【讨论】:

      【解决方案2】:
      #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)...);
      }
      

      在每一行,单个省略号将同时扩展Argsargs。你最终会得到:

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

      ...而不是不正确的:

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

      您可能还对std::result_of 感兴趣,以稍微减少一下这种泄密:

      #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)...);
      }
      

      【讨论】:

      • 那一定是我的英语错误,因为它们对我来说绝对是同一个意思……你能帮我改一下我的意思吗?
      • 不,没关系,我的错我倒着读了。我认为这是因为你用现在时“this does this”谈论解决方案,而 Jared 用将来时“this will do this”谈论解决方案,这让我很困惑。
      猜你喜欢
      • 1970-01-01
      • 2017-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多