【问题标题】:Using std::forward for other than forwarding args to another function使用 std::forward 将 args 转发到另一个函数
【发布时间】:2015-02-17 21:16:46
【问题描述】:

我有很多如下形式的方法

foo(std::string const & name)
    if (name.empty()) {...}

我试图按照 Scott Meyers 关于使用通用引用和 std::forward 的说明创建一个有效地采用多种字符串形式的函数。

从示例中,我了解了如何使用 std::forward 将函数参数转发给另一个函数,但是对于 name.empty() 表达式我该怎么办?

我认为答案是 std::forward(name).empty() 但我可以找到任何实际说明的文档。

【问题讨论】:

    标签: c++ std forward


    【解决方案1】:

    仅当您确实需要转发值类别时才使用std::forward。也就是说,std::forward 用于保证如果使用左值参数调用您的函数,那么它将使用左值参数调用另一个函数,如果使用右值参数调用您的函数,那么它将使用右值参数调用另一个函数论据。

    如果您想检查字符串是否为空,参数是左值还是右值并不重要——string::empty 函数的行为不应有所不同。所以你不需要std::forward。相反,只需 name.empty() 就足够了。

    【讨论】:

    • 在同一个参数上多次使用std::forward很可能是个错误,因为在第一次出现std::forward时,右值可能会被移走。
    【解决方案2】:

    有一种简单的方法可以确定何时使用std::forward

    想象一下,您的传入参数不是T&& t,而是T t——一个值参数而不是转发引用。如果您在第二种情况下调用std::move(t),那么在第一种情况下调用std::forward<T>(t) 是个好主意。

    std::forward 是一个有条件的移动。如果引用是传入的右值,它将调用move,如果它不是右值,它将几乎什么都不做。

    下一个问题是,你应该什么时候move一个值参数?

    嗯,第一条一般规则是,您应该在最后一次在其范围内引用它时移动值参数。您将其状态标记为“scratch”,并在最后一次操作中被回收。

    还有其他几个地方可以使用move

    如果您将其分解为单个组件(如元组的部分),并且您知道访问将被隔离到部分(std::get<N>.member),并且没有不变量可以被违反,然后move 将告诉代码该组件可以从对象中撕下。从这个意义上说,您最终可以对同一个变量多次调用move,但每次您在概念上只移动它的一部分。

    这有时与在组件本身上调用 move 不同,因为当 foo 包含引用参数时,std::get<i>(std::move(foo)) 的行为与 std::move( std::get<i>(foo) ) 不同。

    【讨论】:

      猜你喜欢
      • 2019-04-11
      • 1970-01-01
      • 2022-12-10
      • 2011-11-07
      • 1970-01-01
      • 2018-07-30
      • 2015-11-30
      • 2020-10-23
      • 2018-05-30
      相关资源
      最近更新 更多