Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 内联函数参数传递_C++_Performance_C++11_Const Reference - Fatal编程技术网

C++ 内联函数参数传递

C++ 内联函数参数传递,c++,performance,c++11,const-reference,C++,Performance,C++11,Const Reference,内联函数是否需要在性能方面通过常量引用传递其参数 与价值相比 foo(T a, T b) 如果我不改变函数中a和b的值?C++11 change是否推荐此处的任何特定内容?根据数据类型,按引用传递比按值传递快。 但是,对于内联函数,函数体(以及所有引用/传入值)被添加到它们所使用的代码行中,因此从技术上讲,没有变量被传递,只有相同区域中的更多代码行 参考文献 这个问题下还有一个非常有用的答案 示例可能具有误导性,已删除- 理论上,没有引用的函数可能会复制到内存中,因为内联函数可能正在修改它们

内联函数是否需要在性能方面通过常量引用传递其参数

与价值相比

foo(T a, T b)

如果我不改变函数中a和b的值?C++11 change是否推荐此处的任何特定内容?

根据数据类型,按引用传递比按值传递快。
但是,对于内联函数,函数体(以及所有引用/传入值)被添加到它们所使用的代码行中,因此从技术上讲,没有变量被传递,只有相同区域中的更多代码行

参考文献

这个问题下还有一个非常有用的答案

  • 示例可能具有误导性,已删除-

理论上,没有引用的函数可能会复制到内存中,因为内联函数可能正在修改它们(即使它实际上没有修改)

在许多情况下,编译器足够聪明,可以选择这种类型的东西,但这取决于编译器和优化设置。此外,如果您的函数调用类变量中的任何非常量成员函数,那么您的编译器必须足够聪明,以检查它们是否也在修改任何内容

通过使用常量引用,基本上可以给它一个相当清晰的指示

编辑:我只是想看一看在ddd中使用GCC4.6编译的简单机器代码。生成的代码看起来是相同的,所以看起来确实被优化了。不过,对于其他编译器来说,这仍然是一种很好的做法,如果没有其他方法,那么可以清楚地表明代码的意图。也有可能存在编译器无法优化的更复杂的情况

此外,还显示在那里生成了相同的位代码。如果关闭优化,则在没有常量引用的情况下,它会稍微长一点。
*1964字节-无常量引用(函数/参数上无其他常量)
*1960字节-没有常量引用,只有其他常量。

*1856字节-带有常量和常量引用。

如果参数是临时的,则传递值只能省略复制构造函数调用



当函数内联时,通过常量引用传递基元类型将不会产生任何代价。但是按值传递一个复杂的左值会带来潜在的昂贵的复制构造函数调用。因此,最好通过常量引用传递(如果别名不是问题)。

如果内联函数将a和b传递给另一个函数,则可能无法优化副本。例如,如果内联函数调用非内联函数
bar(a)
,编译器必须复制,因为bar可能执行
if(&a==&special)
,并且原始调用方可能已通过
special
。请重试,对于非POD类型。是否声明成员函数
const
,对于优化器来说并不重要。常量正确性对于优化器是不可见的,它的设计目的只是帮助程序员(如果违反常量声明,则会给出编译时错误),而不是优化器。@6502:常量正确性在某些情况下会影响优化,虽然我同意,但成员函数的常数并不是其中之一。@Ben Voigt:影响优化的是常数值。引用的常量(如
const X&
)或指针的常量(如
const X*
)对优化器从来都不是一个帮助,因为它是一个声明,没有说明被引用或指向的对象的常量(这些声明只确定指针/引用上的有效操作)。这完全是推测。根据类型,按引用传递比按值传递快。另外,使用引用的代码还有额外的要求(正确处理别名),并且可能需要额外的间接寻址,对于按值传递的本机类型,这是不需要的。很抱歉,由于某些奇怪的原因,我将按值传递指针混在一起了。您是对的,对于某些数据类型,它只会更快。我还向你们指出了支持我的观点,一个值是一个值,一个引用是一个引用。当传递一个const引用的意思是传递一个值时,传递一个const引用是一个错误,它会严重地回击。请参阅@6502:这是一个很好的例子,说明使用引用会使逻辑变得更复杂(
v.push_back(v[0])
是合法的,因为标准库必须包含额外的逻辑)。@BenVoigt:很高兴看到此请求已添加到标准中。声明在哪里?@6502:如果调用
push_back
时引用有效,则标准库有责任对其进行正确处理。@BenVoigt:对不起,我不同意。调用传递引用的函数时,如果被引用对象在函数的持续时间内没有足够长,则这是调用方问题(被调用方对其没有控制权)。AfIK标准并没有说复制操作必须在解除分配之前完成:如果一个实现要这么做,OK,但是一个有效的C++编译器可以使守护进程飞离我的鼻子,仍然保持顺从。顺便说一句,现在使用C++0x时情况更加复杂。。。重新分配可以使用移动构造函数吗?如果是这样的话,仅仅延迟销毁旧存储是不够的……除了别名问题外,还存在生存期问题。@6502:返回值时,肯定存在。对于参数,可能会出现生存期问题,但这种情况非常罕见。无论如何,我会认为它们是混叠问题的一个子集。@ BenVoigt >代码>通过const引用传递原始类型在函数被内联时不会有成本。你的意思是“在成本方面没有益处”?你能确认当函数内联时,通过
const int&
const int
是否有什么好处吗?@Antonio:不,我说的是真的。一般来说,通过
const
reference传递有很大的代价:被调用方除了访问实际数据外,还必须访问一个指针,这意味着两次t
foo(T a, T b)