C++ 将基元类型的常量引用作为函数参数传递

C++ 将基元类型的常量引用作为函数参数传递,c++,compiler-optimization,C++,Compiler Optimization,考虑以下功能: template <class T, class Priority> void MutableQueue<T, Priority>::update(const T& item, const Priority& priority) { ... } 模板 void MutableQueue::update(常量T和项、常量优先级和优先级) { ... } 如果优先级类型可以放在寄存器中,现代x86-64编译器是否足够智能,可以通过值而

考虑以下功能:

template <class T, class Priority>
void MutableQueue<T, Priority>::update(const T& item, const Priority& priority)
{
   ...
}
模板
void MutableQueue::update(常量T和项、常量优先级和优先级)
{
...
}

如果优先级类型可以放在寄存器中,现代x86-64编译器是否足够智能,可以通过值而不是引用传递优先级参数?

这完全取决于平台和编译器,参数传递给函数的方式也是如此。
这些细节在程序运行的系统的ABI中定义;有些具有大量寄存器,因此主要使用它们。有些人把它们都推到了一起。有些将它们混合在一起,直到第N个参数


同样,这是你不能依赖的东西;不过,你可以用几种方法来检查它。C++语言没有登记的概念。< /P> < P> AS @黑色,优化是编译器和平台相关的。这就是说,当使用一个好的优化编译器时,我们通常希望每天都会进行大量优化。例如,我们依靠函数内联、寄存器分配、在可能的情况下将常量乘法和除法转换为位移位等

回答你的问题

如果优先级类型可以放在寄存器中,现代x86-64编译器是否足够智能,可以通过值而不是引用传递优先级参数

我就试试看。你自己看看:

  • ()
  • ()
代码如下:

template<typename T>
T square(const T& num) {
   return num * num;
}

int sq(int x) {
  return square(x);
}
模板
T平方(常数T和数值){
返回num*num;
}
整数平方(整数x){
返回方(x);
}
GCC
-O3
-O2
-O1
可靠地执行此优化

另一方面,Clang3.5.1似乎没有执行这种优化

你应该指望这样的优化发生吗?不是总是,也不是绝对的——C++标准没有说明什么时候发生这样的优化。在实践中,如果您使用的是GCC,那么您可以“预期”进行优化


如果您绝对希望确保进行此类优化,您将希望使用。

编译器可以进行优化,但不是强制性的

要强制通过“最佳”类型,可以使用boost:

const T&
(其中通过值传递是正确的)替换为
call_traits::param_type

因此,您的代码可能会变成:

template <class T, class Priority>
void MutableQueue<T, Priority>::update(call_traits<T>::param_type item,
                                       call_traits<Priority>::param_type priority)
{
   ...
}
模板
void MutableQueue::update(调用特性::参数类型项,
调用特性::参数类型(优先级)
{
...
}

我想是的。但是,如果实现暴露于外部模块,它必须满足ABI要求——在这种情况下,引用就是引用。一般来说,您希望避免对原语的引用—有很多方法可以做到这一点。我的猜测是,如果
T
类型的实例可以放入寄存器,编译器将通过副本传递。否则它可能会通过指针传递变量。看起来编译器确实进行了优化。它基本上生成了一个优化版本(如内联函数或按值传递)和一个符合ABI要求的版本(可能未使用,只是放在代码中)。执行此替换的优化似乎是
-fipa sra
。看来叮当声并不支持它。