简体   繁体   English

成员函数调用的对象右值传播

[英]Object rvalue propagation for member function calls

I have a struct F with a function foo that has different implementation whether F is a temporary or not我有一个带有函数foo的结构F ,无论F是否是临时的,它都有不同的实现

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

Another struct A has a copy of F and in its function bar calls F::foo .另一个结构A有一个F的副本,并且在它的函数bar调用F::foo I want to use the correct version of F::foo() .我想使用正确版本的F::foo() Therefore the implementation is:因此,实现是:

struct A{

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

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

  F f;
};

I'm wondering if I really have to provide two implementations of A::bar() .我想知道我是否真的必须提供A::bar()两个实现。 Isn't there a smart way to use std::forward to automatically decide which F::foo() should be used?难道没有一种聪明的方法可以使用std::forward自动决定应该使用哪个F::foo()吗?


An attempt:一次尝试:

struct B{

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

However, this does not work.但是,这不起作用。 It calls F::foo() && every time.它每次都调用F::foo() &&


Complete example完整示例

No, there is no shortcut available at this point and you will need to stick to the verbose version.不,此时没有可用的快捷方式,您需要坚持使用详细版本。 But have a look at p0847 , "Deducing this ".但是看看p0847 ,“推导this ”。 Not sure what the status of this proposal is, however.但是,不确定此提案的状态如何。 From the abstract:从摘要:

We propose a new mechanism for specifying or deducing the value category of an instance of a class.我们提出了一种用于指定或推导类实例的值类别的新机制。 In other words, a way to tell from within a member function whether the object it's invoked on is an lvalue or an rvalue, and whether it is const or volatile.换句话说,一种从成员函数内部判断它被调用的对象是左值还是右值,以及它是 const 还是 volatile 的方法。

You can use a non-member function template:您可以使用非成员函数模板:

struct B{

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

Depending on other function parameters, you might want to restrict the type of TB such that is_base_of_v<B, remove_const_t<remove_reference_t<TB>>> .根据其他函数参数,您可能希望限制TB的类型,例如is_base_of_v<B, remove_const_t<remove_reference_t<TB>>>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM