[英]Can I let the C++ compiler decide whether to pass-by-value or pass-by-reference?
看看这个假设的头文件:
template <class T>
class HungryHippo {
public:
void ingest(const T& object);
private:
...
}
现在,对于HungryHippo<string>
来说,你想要ingest
对字符串的引用是有道理的 - 复制字符串可能非常昂贵! 但对于HungryHippo<int>
它的含义却不那么明显。 直接传递一个int
可能非常便宜(大多数编译器都会在寄存器中执行它),但是将引用传递给int
是一个额外的不必要的间接级别。 这一切都适用于返回值。
有没有办法向编译器建议“嘿,我不会修改参数,所以你决定是通过值还是通过引用来传递,这取决于你认为哪个更好”?
一些可能相关的事情:
template <class T, bool PassByValue> class HungryHippo
然后专门研究PassByValue
手动伪造这个效果。 如果我想得到真正的幻想,我甚至可以根据sizeof(T)
和std::is_trivially_copyable<T>
来推断PassByValue
。 无论哪种方式,当实现看起来几乎相同时,这是一项额外的工作,我怀疑编译器可以更好地决定是否通过值传递。 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:
...
};
这实际上是否会对您的实际代码/编译器组合产生很大影响,我不确定。 一如既往,你必须运行一些实际的基准测试,看看会发生什么......
虽然诸如boost提到的call_traits<T>
之类的技巧做了他们声称在这种情况下做的事情,但我认为你假设编译器在最重要的情况下还没有进行这种优化。 毕竟,这是微不足道的。 如果你接受const T&
和sizeof(T) <= sizeof(void*)
,那么C ++引用语义强加的不变量允许编译器简单地在整个函数体中替换它,如果它是胜利的话。 如果不是,那么最坏情况的开销是函数序言中的一个指向arg的引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.