std :: forward没有完美的转发?

 yf_992258 发布于 2023-02-10 09:55

建议std::forward通常仅限于完美转发函数模板参数的规范用例; 一些评论员甚至说这是唯一有效的用途std::forward.但考虑这样的代码:

// Temporarily holds a value of type T, which may be a reference or ordinary
// copyable/movable value.
template 
class ValueHolder {
 public:
  ValueHolder(T value)
    : value_(std::forward(value)) {
  }


  T Release() {
    T result = std::forward(value_);
    return result;
  }

 private:
  ~ValueHolder() {}

  T value_;
};

在这种情况下,不会出现完美转发的问题:由于这是一个类模板而不是一个函数模板,客户端代码必须明确指定T,并可以选择是否以及如何对其进行ref-qualify.出于同样的原因,论证std::forward不是"普遍参考".

尽管如此,这std::forward似乎是一个很好的选择:我们不能把它排除在外,因为当它T是一个只移动类型时它不起作用,我们不能使用std::move它,因为当它T是一个左值引用类型时它不起作用.当然,我们可以部分专门ValueHolder使用直接初始化引用和std::move值,但这似乎std::forward是工作时的过度复杂.对于以下含义,这似乎也是一个合理的概念匹配std::forward:我们试图通常转发可能会或可能不会引用的内容,只有我们将它转​​发给函数的调用者,而不是我们调用的函数.我们自己.

这是一个合理的用途std::forward吗?有没有理由避免它?如果是这样,那么首选的替代方案是什么?

1 个回答
  • std::forward是一个条件move广播(或更技术上的左右角色),仅此而已.虽然在完美的转发环境之外使用它是令人困惑的,但如果相同的条件move适用,它可以做正确的事情.

    我很想使用一个不同的名字,即使只是一个薄的包装forward,但我不能想到一个好的上述情况.

    或者,使条件移动更明确.也就是说,

    template<bool do_move, typename T>
    struct helper {
      auto operator()(T&& t) const
      -> decltype(std::move(t))
      {
          return (std::move(t));
      }
    };
    template<typename T>
    struct helper<false, T> {
      T& operator()(T&& t) const { return t; }
    };
    template<bool do_move, typename T>
    auto conditional_move(T&& t)
     ->decltype( helper<do_move,T>()(std::forward<T>(t)) )
    {
        return ( helper<do_move,T>()(std::forward<T>(t)) );
    }
    

    如果bool是假的话,这是一个noop传递,如果是move真的.然后,您可以使您的等效std::forward更明确,更少依赖于用户理解C++ 11的神秘秘密来理解您的代码.

    使用:

    std::unique_ptr<int> foo;
    std::unique_ptr<int> bar = conditional_move<true>(foo); // compiles
    std::unique_ptr<int> baz = conditional_move<false>(foo); // does not compile
    

    第三方面,你在上面做的事情要求对rvalue和lvalue语义有相当深刻的理解,所以也许forward是无害的.

    2023-02-10 10:00 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有