c++ - const ref 传递的模板化参数是否优化为在足够小的时候按值传递?
问题描述
当一个标准函数接受一个模板化的参数而不修改它时,它似乎总是接受一个const ref
(例如:std::vector::insert)。
这是否意味着参数之类的bool
函数将变为std::vector<bool>::insert(const bool& value)
?
或者是否有一些优化可以std::vector<bool>::insert(bool value)
代替它?如果是,我自己的模板函数也会从中受益吗?
解决方案
std::vector
是一个模板,因此std::vector<bool>::insert()
是根据定义inline
。
现代编译器很容易“看穿”inline
调用中的引用并将它们全部优化。
对于像这样的小对象int
,按引用传递和按值传递没有区别。
例子:
struct A {
int func1(const int& x) { return x + 1; }
int func2(int y) { return y + 1; }
};
int func1(int x) {
A a;
return a.func1(x);
}
int func2(int y) {
A a;
return a.func2(y);
}
生成的代码(godbolt链接):
func1(int): # @func1(int)
lea eax, [rdi + 1]
ret
func2(int): # @func2(int)
lea eax, [rdi + 1]
ret
如果您通过共享库公开 API,则通过引用传递可能会导致额外的取消引用。这是因为在 C++ ABI 中,按引用传递实际上是通过指针发生的。但是对于inline
电话来说,这通常不是问题。
另一方面,如果复制或使用大对象涉及副作用,则按值传递大对象可能不容易优化。所以对于一个通用模板,通过引用传递是一个聪明的设计选择。
推荐阅读
- html - 当文本数量不同时,底部水平对齐按钮
- python - DBSCAN 根据什么检测异常值?异常值的标准是什么
- php - 如何通过 Swift 使用 multipart/form-date 将文件发送到服务器
- c++ - QStandardItemModel 中项目的重新分配
- maven-plugin - 使用plantuml maven插件生成UML图时出错
- firebase - Flutter-Firebase 存储上传视频
- php - Laravel SQL 查询返回重复项
- javascript - 复选框数据过滤器和 if else 语句
- javascript - KoaJS ctx.redirect() 在 Chrome 中导致 ERR_TOO_MANY_REDIRECTS
- batch-file - 将具有相同名称但扩展名不同的文件列表复制到新目录