首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用std::转发非转发引用

使用std::转发非转发引用
EN

Stack Overflow用户
提问于 2018-02-20 12:45:33
回答 1查看 356关注 0票数 2

我试图弄清楚在下面的代码中使用std::forward是否有意义,即使它不是一个转发(=通用)引用。请原谅代码的数量,但这是我试图实现的精简版本。

代码语言:javascript
复制
template <class... Args>
class event_dispatcher {
private:
  using func_t = std::function<bool(Args...)>;

public: 
  bool operator()(Args... args) const {
    for (auto& f : funcs) {
      if (!f(args...))
        return false;
    }
    return true;
  }

  template <class F>
  std::enable_if_t<std::is_invocable_r_v<bool, F, Args...>>
  add(F&& f) {
    funcs.emplace_back(std::forward<F>(f));
  }

  template <class F>
  std::enable_if_t<!std::is_invocable_r_v<bool, F, Args...> && std::is_invocable_v<F, Args...>>
  add(F&& f) {
    add([f_ = std::forward<F>(f)](Args... args){
         std::invoke(f_, std::forward<Args>(args)...); // <-- this is the one I am asking about!
         return true;
       });
  }

private:
  std::vector<func_t> funcs;
};

这样做的想法是,如果传递给add()的可调用函数不返回bool,我们将将其包装在一个具有此功能的lambda中。

现在,如果我直接传递args...,它将始终工作,但是如果Args中的任何一个是rvalue,那么它将不必要地执行一个副本而不是移动。如果我使用的是std::move(args)...,那么如果Args中的任何一个是lvalue,它就不能工作。在这里使用std::forward<Args>(args)...似乎解决了这些问题,并且在任何情况下都尽可能高效地工作,但我担心我遗漏了一些东西,因为我使用std::forward进行非转发引用,而且通常,我在整个引用中遇到很多麻烦--崩溃/ rvalue引用/ std::move /std::正向问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-20 17:27:26

std::move不移动,std::forward不向前移动。

std::forward是一个有条件的动作。如果std::forward<T>是值或rvalue引用,则T会移动。

这与您想要移动args...的时间是一致的,所以在这里是合适的。

这样的注释应该是个好主意,就像在简单转发引用之外使用std::forward的任何情况一样。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48885599

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档