【问题标题】:std::forward and ref-qualifiers for member functions成员函数的 std::forward 和 ref 限定符
【发布时间】:2016-10-29 20:36:56
【问题描述】:

我处于使用std::forward 的位置,只要我有转发引用,我想知道其中一些是否不必要甚至是错误的。例如,在 std::begin() 呼叫中使用 std::forward

由于类能够根据调用是否将对象作为右值进行重载其成员函数https://akrzemi1.wordpress.com/2014/06/02/ref-qualifiers/,我假设模板化函数将尽可能高效,如果你知道您将对象转发到的内部函数是非变异的和/或是对象的成员函数。例如

template <typename Something>
void do_something(Something&& something) {
    std::forward<Something>(something).do_something();
    auto iter = std::begin(std::forward<Something>(something));
    for_each(iter, std::end(std::forward<Something>(something), []() {});
}

我看到了这个问题 (When not to use std::forward with r-values?),但它没有解决成员函数 ref-qualifiers 并且也没有明确说明当您无法访问内部函数定义时的最佳实践是什么打电话。

是否有关于何时不使用 std::forward 的一般准则来解决我提到的问题?还是我遗漏了一些关键概念?

【问题讨论】:

  • std::begin()/end() 在这里不是一个很好的例子——“rvalue”版本只会产生 const 迭代器,没有进行 ref 限定。
  • @Barry 这样做是让我想到这个问题的原因。我只是想弄清楚这件事的背景,以便人们了解我来自哪里。
  • 如果您使用右值版本,您必须接受这样一个事实,即被调用的函数可能会拉出您的对象并在之后留下一个有效但类似空的状态
  • @krzaq 当你知道你的函数是非变异的和/或者是一个成员函数的情况下呢?
  • @Curious 那么,我发表评论而不是直接回答是有原因的;)

标签: c++ c++11 templates c++14 perfect-forwarding


【解决方案1】:

除非您知道您将拥有的类型,否则请避免在同一函数中对同一对象多次使用std::forward,因为第二次可能会移动您的对象。

// assuming implementation which really need pass by value instead of const reference
template <typename T> void pass_by_value(T t) { std::cout << t; }

template <typename T>
void foo(T&& t)
{
    pass_by_value(std::forward<T>(t));
    pass_by_value(std::forward<T>(t));
}

foostd::string 的通话

foo(std::string("Hello world")); // or "Hello world"s

可能会调用等价于

    pass_by_value(std::string("Hello world"));
    pass_by_value(std::string("")); // Moved string...

【讨论】:

    【解决方案2】:

    问题是在对象移动后使用(“窃取”)。如果somethingdo_something 的多行中使用,则仅在最后一行使用std::forward 以防止出现问题。

    【讨论】:

      猜你喜欢
      • 2020-03-24
      • 1970-01-01
      • 2013-10-28
      • 1970-01-01
      • 2015-10-03
      • 2015-08-21
      • 2019-04-11
      • 2016-09-12
      • 2013-08-24
      相关资源
      最近更新 更多