37|参数传递的正确方法和模板的二进制膨胀
吴咏炜
该思维导图由 AI 生成,仅供参考
你好,我是吴咏炜。
上一讲我们讨论的视图类型的对象,通常和内置类型的对象一样,是使用传值的方式来进行传参的。这种方式非常简单,也是比较推荐的 C++ 的做法,但这种方式存在对对象类型的限制。在对象比较大的时候,或者可能比较大的时候,按值传参就可能有性能问题。这包括了大部分的函数模板,除非你能预知用来实例化模板的参数。此外,还有很多对象可能是不可复制、甚至不可移动的,显然,这些对象你也不可能按值传参。此时,你就只能使用引用或指针来传参了。
参数传递的方式
函数的参数有入参、出参和出入参之分。入参是最常见的情况,意味着一个参数是让函数来使用的。出参表示一个参数是函数来写的,它必须是一个引用或指针,在现代 C++ 里已经较少推荐,因为返回对象(包括结构体、pair、tuple 等)往往可导致更加清晰、更加安全、同时性能也不下降的代码。出入参是一种中间情况,参数会被函数同时读和写。它也是引用或指针,常常是一个序列的对象(如 vector 和 string),里面本来就有内容,并在函数执行的过程中让函数继续往里添加内容。
对于现代 C++,非可选的出参和出入参通常使用引用方式,这样的代码写起来会更加方便。而可选的出参和出入参则一般使用指针方式,可以用空指针表示这个参数不被使用。而入参的情况就复杂多了:
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文深入讨论了C++参数传递的正确方法和模板的二进制膨胀问题。首先介绍了函数参数的入参、出参和出入参的区别,以及现代C++中推荐的参数传递方式。接着详细讨论了不同情况下的参数传递方式,包括不可选参数、大对象、移动友好的参数等。文章还介绍了转发引用和auto&&的使用方法,以及转发引用可能存在的问题。此外,通过举例和技术原理深入探讨了函数参数传递的最佳实践和模板二进制膨胀的问题。对于C++开发者来说,本文提供了深入的技术细节和实用的建议,有助于他们更好地理解和应用参数传递的最佳实践。文章还讨论了通过退化和公共基类消减二进制膨胀的方法。总的来说,本文为读者提供了深入的技术细节和实用的建议,有助于他们更好地理解和应用参数传递的最佳实践,以及解决模板二进制膨胀的问题。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《现代 C++ 编程实战》,新⼈⾸单¥59
《现代 C++ 编程实战》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(3)
- 最新
- 精选
- 罗 乾 林课后思考: 1.const std::unique_ptr<A> & 2.如果传入参数为数组,T类型推导将为数组的引用,is_array_v<T>结果为false,因为此时T为引用. remove_extent_t<T>结果仍然是数组的引用,span这里编译不通过
作者回复: 1. 参考第 41 讲。一般不建议用 const unique_ptr& 传参。 2. 正确。
2023-04-21归属地:上海31 - 李云龙由于unique_ptr不支持复制,那么使用 unique_ptr<T>& 作为函数的传入传出参数比较合适。
作者回复: 请直接参考第 41 讲。
2023-11-19归属地:美国 - coming#include <span> int main() { auto lambda = [](const auto& x, const auto& y) { // 处理并返回 }; int n; long long lln; std::span<const int> sp; lambda(n, lln); lambda(lln, n); lambda(n, 1); lambda(n, sp[0]); lambda(sp[0], lln); return 0; } 我使用https://cppinsights.io/s/a77543e0, 确认是实例化了三个 #ifdef INSIGHTS_USE_TEMPLATE template<> inline /*constexpr */ void operator()<int, long long>(const int & x, const long long & y) const { } #endif #ifdef INSIGHTS_USE_TEMPLATE template<> inline /*constexpr */ void operator()<long long, int>(const long long & x, const int & y) const { } #endif #ifdef INSIGHTS_USE_TEMPLATE template<> inline /*constexpr */ void operator()<int, int>(const int & x, const int & y) const { } #endif 老师能说下, 哪一讲,讲了这个推导规则吗? 我有点懵
作者回复: 泛型lambda表达式在第16讲介绍,不过当时确实讲得比较简单。需要记住的是 它本质上是具有 operator() 成员函数模板的类的函数对象。对于这个例子,相当于如下的 operator(): template <typename T, typename U> auto operator()(const T& x, const U& y) { … } 然后就是普通的模板参数匹配和推导了。这样是不是好理解一点?
2023-08-14归属地:上海3
收起评论