1
11
内置类型和小对象(如STL迭代器)通常应按值传递。 这部分是为了增加编译器的优化机会。令人惊讶的是,编译器很难知道引用参数是否是另一个参数或全局参数的别名-它可能必须通过函数多次从内存中重新读取对象的状态,以确保值没有更改。
这就是C99的原因
|
2
5
如果要在本地修改
|
3
2
如果正在传递的对象是智能指针(即,它自己进行引用计数),则通过值传递可能更合理。
不过,到目前为止,我的推理路线存在一个问题——通过传递值,您将失去参数的“常量”。也许您应该使用“by reference”语义。。。 |
4
2
不要忘记,当您处理具有奇怪的复制/分配语义的对象时,有些情况会有所不同。
|
5
1
此外,当T是简单类型(int、bool等)时,通常使用foo(tt)。 |
6
1
另一个没有提到的例子是大量使用该对象。假设您传递一个包含5个整数的结构作为成员。如果你打算大量访问函数中的所有5个函数,那么在某一点上,解引用成本超过了复制成本。但是,您必须运行探查器才能知道这是什么时候。 不过,我应该指出,像STL容器这样在堆上分配内存的东西,如果可以避免的话,几乎不应该按值传递,因为堆分配比堆栈分配慢得多。 |
7
1
在这种情况下,您没有其他选项,只能按值传递参数。当然,boost可以处理这个问题。但如果没有助推,我们必须按值传递一个值。
|
8
1
“按常量引用传递”和“按值传递”在概念上相同的原因是它们都不能修改原始值。
这就是说,它确实可能会使您的代码速度变慢。在过去,我一直倾向于按值传递,除非我知道这样做是(或将是)性能问题。我可能需要稍微修改一下,将passbyconst引用作为更好的选项。 |
9
1
如果函数最直接的实现涉及到在本地修改参数值,那么按值而不是按常量引用传递它是有意义的 例如,strcpy的单行版本:
|
10
1
两个非常具体的案例: 当您编写具有强异常保证的赋值运算符时,您可以像
或者,您可以认识到,发生的第一件事是,您制作了一份副本,并将其作为通话的一部分
如果您有一个具有所有权语义的智能指针,例如。
|
11
1
前者在函数内创建对象的副本。这意味着可以在函数中安全地修改该值。它还意味着发生了对象的完整副本,如果对象很大,这可能是一个问题。 后者为对象创建别名,并声明不能在对象内修改。不会进行复制,但对函数内对象的每次访问都需要取消引用。编译器为我们解决了这一问题,但知道这一点仍然很重要。 如果您有一个通常在寄存器中传递的类型,那么这种差异就变得非常重要。例如,在某些平台上,整数、浮点数甚至是4浮点向量。性能方面的考虑表明,您希望对象在寄存器中尽可能长时间地保留,而不将自身写回内存,而传递值使这种情况更可能发生。 因此,对于基本类型(char、short、int、long、float、double),您应该始终更喜欢按值传递 除非 |
12
0
|
13
0
有些例程需要一个副本,因此不应通过引用传递。例如,国际象棋程序的移动生成器可能需要(递归地)处理当前位置的副本,而不是实际修改位置的原始实例。 |
14
0
this answer . 这是一个 SymLink 答案是肯定的。请在那里投票,如果有:) |
15
0
Boost.CallTraits 是一种鲜为人知但很有用的工具,用于传递参数和结果,对于所讨论的类型来说,这应该是最有效的方法。 |
rookie · 检查函数模板的所有参数包参数是否属于int 1 年前 |
ivaigult · -W转换和隐式字符串到布尔类型转换 1 年前 |
rainer · 后台插入程序的初始化 1 年前 |
Community wiki · 以理智、安全和高效的方式复制文件 1 年前 |
Shefali Kanaujia · 对C中向量的向量进行排序++ 1 年前 |
Ma Joonyoung · 粗粒度和细粒度链表的时间比较 1 年前 |