前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++核心准则编译边学-F.16 对于输入参数来说,拷贝代价小的传值,其他传递const参照

C++核心准则编译边学-F.16 对于输入参数来说,拷贝代价小的传值,其他传递const参照

作者头像
面向对象思考
发布2020-03-25 15:21:39
8370
发布2020-03-25 15:21:39
举报

F.16: For "in" parameters, pass cheaply-copied types by value and others by reference to const(对于输入参数来说,拷贝代价小的传值,其他传递const参照)

Reason(原因)

Both let the caller know that a function will not modify the argument, and both allow initialization by rvalues.

两种方式都可以让调用者知道函数不会修改参数并且都可以通过右值初始化。

What is "cheap to copy" depends on the machine architecture, but two or three words (doubles, pointers, references) are usually best passed by value. When copying is cheap, nothing beats the simplicity and safety of copying, and for small objects (up to two or three words) it is also faster than passing by reference because it does not require an extra indirection to access from the function.

什么是“拷贝代价小”和机器架构有关,但是2到3个字(双精度数,指针,引用)通常最适合传值。如果拷贝代价小,没有方法可以超过拷贝的简单和安全,另外,对于小对象(不超过2到3个字)来说,由于函数不需要额外间接访问,因此传值会比传址的速度更快。

Example(示例)
代码语言:javascript
复制
代码语言:javascript
复制
void f1(const string& s);  // OK: pass by reference to const; always cheap

void f2(string s);         // bad: potentially expensive

void f3(int x);            // OK: Unbeatable

void f4(const int& x);     // bad: overhead on access in f4()

For advanced uses (only), where you really need to optimize for rvalues passed to "input-only" parameters:

(只)对于高级的用法,需要优化为向输入参数传递右值引用的情况有:

  • If the function is going to unconditionally move from the argument, take it by &&. See F.18. 如果函数会无条件的移动参数的内容,使用&&。参考F.18
  • If the function is going to keep a copy of the argument, in addition to passing by const& (for lvalues), add an overload that passes the parameter by && (for rvalues) and in the body std::moves it to its destination. Essentially this overloads a "will-move-from"; see F.18. 如果函数会管理一个参数的拷贝,除了使用功能const&(对于左值)以外,增加一个使用&&(对于右值)传递参数的重载函数并且在内部使用std::move移动参数内容到目标上。本质上这个重载是一个“将要移动形式”;参考F.18
  • In special cases, such as multiple "input + copy" parameters, consider using perfect forwarding. See F.19. 对于
  • 特殊场合,例如多重“输入+拷贝”参数,考虑使用完美的forward。参考F.19

译者注:关于forward,请参考作者的以下文章:

https://mp.weixin.qq.com/s/RJb7PhPA1xoDEIwJRNxrCg

Example(示例)
代码语言:javascript
复制
代码语言:javascript
复制
int multiply(int, int); // just input ints, pass by value

// suffix is input-only but not as cheap as an int, pass by const&
string& concatenate(string&, const string& suffix);

void sink(unique_ptr<widget>);  // input only, and moves ownership of the widget

Avoid "esoteric techniques" such as:

避免使用“只有高手才懂的技术”,例如:

  • Passing arguments as T&& "for efficiency". Most rumors about performance advantages from passing by && are false or brittle (but see F.18 and F.19). 为了提高效率而使用T&&。许多通过传递&&获得性能优势的传言都是假的或者脆弱的。(但是请参照F.18和F.19)
  • Returning const T& from assignments and similar operations (see F.47.) 通过复制或者类似操作返回const T&(参考F.47)
Example(示例)

Assuming that Matrix has move operations (possibly by keeping its elements in a std::vector):

假设Matrix实现了移动操作(例如使用std::vector保管元素)

代码语言:javascript
复制
代码语言:javascript
复制
Matrix operator+(const Matrix& a, const Matrix& b)
{
    Matrix res;
    // ... fill res with the sum ...
    return res;
}

Matrix x = m1 + m2;  // move constructor

y = m3 + m3;         // move assignment
Notes(注意)

The return value optimization doesn't handle the assignment case, but the move assignment does.

返回值优化不会处理赋值的情况,但是移动赋值会。

译者注:

1.返回值优化(RVO)已经足够好,不要在寻求更高级的技术了。

2.移动构造函数和移动赋值请参照作者文章:

https://mp.weixin.qq.com/s/kL7TWKa0EqChoSS7oFnRew

A reference may be assumed to refer to a valid object (language rule). There is no (legitimate) "null reference." If you need the notion of an optional value, use a pointer, std::optional, or a special value used to denote "no value."

可以假设引用参照的是有效对象(语言准则)。不存在(合理的)“空引用”。如果需要可选值概念,使用指针,std::optional或者特殊值表示“没有值”。

Enforcement(实施建议)
  • (Simple) ((Foundation)) Warn when a parameter being passed by value has a size greater than 2 * sizeof(void*). Suggest using a reference to const instead. (简单)((基本准则)) 当传值的大小超过2*sizeof(void*)时,报警。建议使用const引用。
  • (Simple) ((Foundation)) Warn when a parameter passed by reference to const has a size less than 2 * sizeof(void*). Suggest passing by value instead. (简单)((基本准则))当小于2*sizeof(void*)的参数使用const传址时,报警。
  • (Simple) ((Foundation)) Warn when a parameter passed by reference to const is moved. (简单)((基本准则))当使用const传址的参数的内容被移动时,报警。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 面向对象思考 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • F.16: For "in" parameters, pass cheaply-copied types by value and others by reference to const(对于输入参数来说,拷贝代价小的传值,其他传递const参照)
    • Reason(原因)
      • Example(示例)
        • Example(示例)
          • Example(示例)
            • Notes(注意)
              • 1.返回值优化(RVO)已经足够好,不要在寻求更高级的技术了。
                • Enforcement(实施建议)
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档