【问题标题】:Object rvalue propagation for member function calls成员函数调用的对象右值传播
【发布时间】:2020-10-14 11:28:47
【问题描述】:

我有一个结构 F 和一个函数 foo,无论 F 是不是临时的,它都有不同的实现

struct  F{
  void foo() &  { std::cout << "F::foo() &" << std::endl; }
  void foo() && { std::cout << "F::foo() &&" << std::endl; }
};

另一个结构A 有一个F 的副本,并在其函数bar 中调用F::foo。我想使用正确版本的F::foo()。因此实现是:

struct A{

  void bar() & {
    f.foo();
  }

  void bar() && {
    std::move(f).foo();
  }

  F f;
};

我想知道我是否真的必须提供A::bar() 的两个实现。难道没有一种聪明的方法可以使用std::forward 来自动决定应该使用哪个F::foo()


一次尝试:

struct B{

  void bar() {
    std::forward<F>(f).foo();
  }
  
  F f;
};

但是,这不起作用。它每次都会调用F::foo() &amp;&amp;


Complete example

【问题讨论】:

    标签: c++ rvalue-reference rvalue


    【解决方案1】:

    您可以使用非成员函数模板:

    struct B{
    
      template<typename TB>
      friend void bar(TB&& self) {
        std::forward<TB>(self).f.foo();
      }
      
      F f;
    };
    

    根据其他函数参数,您可能希望限制TB 的类型,例如is_base_of_v&lt;B, remove_const_t&lt;remove_reference_t&lt;TB&gt;&gt;&gt;

    【讨论】:

    • 真棒黑客。我也在寻找基于friend 的解决方案,但最终得到了一些不那么优雅的解决方案。不错!
    • @lubgr 你只是知道太多 C++17。对我来说,if constexpr 在我脑海中的某个地方,而forward 则更多;)
    【解决方案2】:

    不,此时没有可用的快捷方式,您需要坚持使用详细版本。但是看看p0847,“推论this”。但是,不确定该提案的状态如何。摘自:

    我们提出了一种新机制,用于指定或推断类实例的值类别。换句话说,一种在成员函数中判断调用它的对象是左值还是右值,以及它是 const 还是 volatile 的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-14
      • 1970-01-01
      • 1970-01-01
      • 2012-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多