C++templates第七章按值传递还是按引用传递?
C++templates第七章按值传递还是按引用传递?
Hoshea Zhang从一开始,C++就提供了按值传递(call-by-value)和按引用传递(call-by-reference)两种参 数传递方式,但是具体该怎么选择,有时并不容易确定:通常对复杂类型用按引用传递的成本更低,但是也更复杂。C++11 又引入了移动语义(movesemantics),也就是说又多了一 种按引用传递的方式。
按值传递
当按值传递时,原则上所有参数都会被拷贝,因此每一个参数都会是被传递实参的一份拷贝,对于class对象,会通过class拷贝构造函数去初始化
调用拷贝构造函数成本会很高,我们可以通过移动语义去优化,如下所示:
1 | template<typename T> |
参数arg会变成是残的一次拷贝,但是不是所有情况都回调用拷贝构造函数:
1 | std::string returnString(); |
在第一次调用中,被传递的参数是左值(lvalue),因此拷贝构造函数会被调用。但是在第 二和第三次调用中,被传递的参数是纯右值,此时编译器会优化参数传递,使得拷贝构造函数不会被调用
按值传递会导致类型退化
1 | template<typename T> |
按引用传递
按const引用传递
为了避免(不必要的)拷贝,在传递非临时对象作为参数时,可以使用 const 引用传递。比如:
1 | template<typename T> |
引用传递不会做类型退化
按引用传递参数时,其类型不会退化(decay)。也就是说不会把裸数组转换为指针,也不会移除 const 和 volatile 等限制符。而且由于调用参数被声明为 Tconst&,被推断出来的模 板参数 T 的类型将不包含 const