前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++核心准则F.55 不要使用可变参数

C++核心准则F.55 不要使用可变参数

作者头像
面向对象思考
发布2020-03-25 15:50:54
4790
发布2020-03-25 15:50:54
举报
文章被收录于专栏:C++核心准则原文翻译

F.55: Don't use va_arg arguments

F.55 不要使用可变参数

Reason(原因)

Reading from a va_arg assumes that the correct type was actually passed. Passing to varargs assumes the correct type will be read. This is fragile because it cannot generally be enforced to be safe in the language and so relies on programmer discipline to get it right.

从va_arg中读出内容的处理假设实际传递的数据类型是正确的。传递可变参数的处理假设数据会按照正确的类型被读取。由于通常这两种假设都不能在语言中强制达成安全,只能依靠编程规范以保证其正确。因此说都是脆弱的。

Example(示例)
代码语言:javascript
复制
int sum(...) {
    // ...
    while (/*...*/)
        result += va_arg(list, int); // BAD, assumes it will be passed ints
    // ...
}

sum(3, 2); // ok
sum(3.14159, 2.71828); // BAD, undefined

template<class ...Args>
auto sum(Args... args) { // GOOD, and much more flexible
    return (... + args); // note: C++17 "fold expression"
}

sum(3, 2); // ok: 5
sum(3.14159, 2.71828); // ok: ~5.85987

译者注:代码中使用了两种现代C++的新特性,一个是C++11中引入的可变参数模板(variadic template),另一个是C++17引入的折叠表达式(fold expression)。

Alternatives(备选方案)
  • overloading 重载
  • variadic templates 可变参数列表
  • variant arguments variant(C++17引入的变体数据,译者注)类型参数。
  • initializer_list (homogeneous) 初始化列表(同类数据的情况)(C++11引入)
Note(注意)

Declaring a ... parameter is sometimes useful for techniques that don't involve actual argument passing, notably to declare "take-anything" functions so as to disable "everything else" in an overload set or express a catchall case in a template metaprogram.

定义一个...参数在无法决定实际参数类型时一种有用的技术,尤其是定义可以接受任何东西的函数以便在重载版本中禁止“任何其他的东西”或者在模板元程序中表示包罗万象的容器。

Enforcement(实施建议)
  • Issue a diagnostic for using va_list, va_start, or va_arg. 发起对使用va_list,va_start或者va_arg的检查。
  • Issue a diagnostic for passing an argument to a vararg parameter of a function that does not offer an overload for a more specific type in the position of the vararg. To fix: Use a different function, or [[suppress(types)]]. 发起针对以下情况的检查:向函数的可变参数可变参数传递单独的实参,而且不存在在可变参数位置定义了特定数据类型参数的重载函数。 修改建议:使用不同的函数或者[[抑制((类型准则群组))]]

觉得本文有帮助?请分享给更多人

关注【面向对象思考】,每天前进一小步

有任何疑问,欢迎留言提问或讨论


面向对象设计,面向对象编程,面向对象思考!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 面向对象思考 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • F.55: Don't use va_arg arguments
    • Reason(原因)
      • Example(示例)
        • Alternatives(备选方案)
          • Note(注意)
            • Enforcement(实施建议)
            相关产品与服务
            容器服务
            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档