简而言之,通过值或const引用传递指针是否更好?
我写了一个简单的函数来探索:
void foo(int* v) { std::cout << *v << endl; }
与
void foo(int* const& v) { std::cout << *v << endl; }
我试着看一下生成的组件,但我不是特别擅长组装,所以我不确定我是否理解其中的区别。但是有区别。在第一种情况下,我们得到:
pushq %rbp
pushq %rbx
subq $8, %rsp
movl (%rdi), %esi
movl std::cout, %edi
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
在const&
案例中,我们再进行一次操作:
pushq %rbp
pushq %rbx
subq $8, %rsp
movq (%rdi), %rax
movl std::cout, %edi
movl (%rax), %esi
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
这种差异意味着什么(三个mov
而不是两个),这意味着什么? (基本上,我有一个结构Foo<T>
,其中T
可能是一个原始指针,我想知道我的函数bar(const T&)
是否应该是bar(typename boost::call_traits<T>::type)
。)。
答案 0 :(得分:9)
按值传递指针,除非您需要引用语义。
通过引用传递几乎可以通过传递指针来实现。您将传递与指针本身相同数量的数据,但会引入额外的间接级别,因此它的效率可能低于传递值。
话虽如此,差异可能很小;所以对于通用代码,通过const引用更简单,除非你真的需要在单个指令的级别进行微优化。如果您这样做,正如您所说,boost::call_traits
可以提供帮助。
答案 1 :(得分:1)
通过引用传递指针将执行以下操作:
Address: 0x00 - 42 (int)
Address: 0x11 - 0x00 (int*)
Address: 0x22 - 0x11 (int* const&)
这基本上是编译器为int * const&amp;生成的内容。实施明智,它可能最终成为int **。
因此,按值传递指针最终会更有效率,因为您将直接复制int的地址,而不会产生第三行的开销。
答案 2 :(得分:0)
对于指针,按值传递。根据定义,将指针传递给指针(这将是引擎盖下发生的事情)不能比传递指针更有效。汇编程序中的额外行(我对此知之甚少)表明它实际上对您来说效率较低。