Cal*_*vin 14 c++ compiler-construction performance pass-by-value pass-by-const-reference
看看这个假设的头文件:
template <class T>
class HungryHippo {
public:
void ingest(const T& object);
private:
...
}
Run Code Online (Sandbox Code Playgroud)
现在,因为HungryHippo<string>
你想要ingest
引用字符串是有意义的 - 复制字符串可能非常昂贵!但对于HungryHippo<int>
它来说,它没那么有道理.int
直接传递可能非常便宜(大多数编译器会在寄存器中执行),但是传递对a的引用int
是一个额外的不必要的间接级别.这一切都适用于返回值.
有没有办法向编译器建议"嘿,我不会修改参数,所以你决定是通过值还是通过引用来传递,这取决于你认为哪个更好"?
一些可能相关的事情:
template <class T, bool PassByValue> class HungryHippo
然后专注来手动伪造这种效果PassByValue
.如果我想得到真正的幻想,我甚至可以PassByValue
根据sizeof(T)
和推断std::is_trivially_copyable<T>
.无论哪种方式,当实现看起来几乎相同时,这是一项额外的工作,我怀疑编译器可以更好地决定是否通过值传递.ingest
是相当复杂的,不值得内联.inline
默认情况下所有模板函数都是如此.该boost::call_traits
标头正是这个问题的交易.检查它在这里.
具体而言,该call_traits<T>::param_type
选项包括以下描述:
如果
T
是小型内置类型或指针,则param_type
定义为T const
,而不是T const&
.如果它们依赖于传递的参数,这可以提高编译器优化函数体中循环的能力,否则传递参数的语义不变(需要部分特化).
在您的情况下,您可以定义ingest
如下:
template <class T>
class HungryHippo {
public:
void ingest(call_traits<T>::param_type object);
// "object" will be passed-by-value for small
// built-in types, but passed as a const reference
// otherwise
private:
...
};
Run Code Online (Sandbox Code Playgroud)
这实际上是否会对您的实际代码/编译器组合产生很大影响,我不确定.一如既往,你必须运行一些实际的基准测试,看看会发生什么......