【发布时间】:2012-11-04 16:42:45
【问题描述】:
看看这个假设的头文件:
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。无论哪种方式,当实现看起来几乎相同时,这都是很多额外的工作,我怀疑编译器可以比我更好地决定是否通过值传递。 -
libc++ 项目似乎通过内联很多函数来解决这个问题,因此编译器可以做出更上一层楼的选择,但在这种情况下,假设ingest的实现相当复杂,不值得内联。 如 cmets 中所述,所有模板函数默认为inline。
【问题讨论】:
-
需要考虑的一点:这听起来像是一个过早优化的好案例。您是否因为这种架构而遇到过性能问题?如果没有,你可能应该做任何语义上有意义的事情。
-
对于整数,通过引用传递几乎与通过值传递一样高效,因此 const 引用对这两种情况都有好处。
-
"在这种情况下,假设摄取的实现相当复杂,不值得内联。"在这种情况下,您别无选择。由于 HungryHippo 是模板,所以必须内联。
-
@Slavik81 这根本不是真的。
-
我想知道为什么编译器(和 ABI 规范)不只是将
const int &视为与int相同。 (对于所有通过值传递比通过 const 引用更有效的内置类型也是如此。)它会破坏任何东西吗?
标签: c++ performance compiler-construction pass-by-value pass-by-const-reference