C ++ - 调用setter的函数 - 如何修饰参数?

时间:2018-02-01 20:25:50

标签: c++ c++11 rvalue-reference

据我所知,当前(后C ++ 11)约定是用可移动类型编写setter,如下所示:

void set_a(A a) {
    a_ = std::move(a);
}

编写另一个调用set_a()的setter或forwarder函数的最佳方法是什么?例如:

void set_ab(A a, B b) {
    set_a(std::move(a));  // like this?
    set_b(b);  // or like this?
}

或者:

void do_one(A a) {  // by value? by const ref? by rvalue-ref?
    do_two(a);  // move?
}
void do_two(A a) {
   obj.set_a(a);
}

我不认为std :: move()在这里是合适的,所以我应该如何编写这个以提高效率,假设优化编译器?

所有这些功能签名是否取决于我是否将最终的A对象存储在某处?

由于

1 个答案:

答案 0 :(得分:1)

如果您有值,则不会重复使用std::move

如果您有左值参考,则不会重复使用std::move

转发参考时,std::forward当且仅当你是左值参考时才移动它。

按价值采取的规则假定:

  1. 您不介意在呼叫站点静默复制

  2. 移动是如此便宜,你把它视为免费

  3. 复制比移动

  4. 贵得多

    如果(1)为假,则在sink参数中使用右值引用(A&&)。现在,来电者必须明确地制作副本。

    如果(2)为假,则应使用完美转发,多次重载,类型擦除安置或无数其他更复杂的解决方案。

    如果(3)为假,请不要打扰move。只需按价值计算。

    如果所有3都是真的,那么您的set_ab看起来像是:

    void set_ab(A a, B b) {
      set_a(std::move(a));
      set_b(std::move(b));
    }