在C++中,各种数值类型的转化是C++编译过程中警告的主要来源,但是,很多时候,我们需要使用各种数值类型,例如我们用数组的某一位表示大小为对应序号的值,这种情况下,经常会涉及多种数值类型。根据C++ Programming Language中的建议,在数值类型转换时,使用narrow_cast来实现运行时安全,这里给出C++14版本的实现。

  1. // there is no implicit conversion from Source to Target
  2. template <typename Target, typename Source,
  3. typename = std::enable_if_t<
  4. !std::is_same<std::common_type_t<Target, Source>, std::decay_t<Target>>::value>>
  5. inline Target narrow_cast(Source v)
  6. {
  7. static_assert(!std::is_reference<Target>::value, "The target couldn't be reference");
  8. static_assert(std::is_arithmetic<Source>::value, "The parameter of narrow_cast should be arithmetic");
  9. static_assert(std::is_arithmetic<Target>::value, "The return value of narrow_cast should be arithmetic");
  10.  
  11. // using Target_U = std::remove_reference_t<Target>;
  12. // using Source_U = std::remove_reference_t<Source>;
  13.  
  14. auto r = static_cast<Target>(v);
  15. if (static_cast<Source>(r) != v)
  16. throw std::runtime_error("narrow_cast<>() failed");
  17. return r;
  18. }
  19.  
  20. // there is implicit conversion from Source to Target
  21. template <typename Target, typename Source,
  22. typename = std::enable_if_t<
  23. std::is_same<std::common_type_t<Target, Source>, std::decay_t<Target>>::value>>
  24. inline constexpr std::remove_reference_t<Source> narrow_cast(Source v)
  25. {
  26. static_assert(!std::is_reference<Target>::value, "The target couldn't be reference");
  27. static_assert(std::is_arithmetic<Source>::value, "The parameter of narrow_cast should be arithmetic");
  28. static_assert(std::is_arithmetic<Target>::value, "The return value of narrow_cast should be arithmetic");
  29.  
  30. return static_cast<Target>(v);
  31. }

下面给出,使用Catch写的简单测试用例:

  1. #define CATCH_CONFIG_MAIN
  2. #include "catch.hpp"
  3. #include <cmath>
  4.  
  5. TEST_CASE("Test narrow_cast", "[narrow_cast]")
  6. {
  7. int i = ;
  8. long long j = ;
  9. long long& k = j;
  10. REQUIRE(narrow_cast<long>(k) == );
  11. REQUIRE(narrow_cast<long>(i) == );
  12. long long very_big = pow(, );
  13. bool exception = false;
  14. try
  15. {
  16. narrow_cast<long>(very_big) == very_big;
  17. }
  18. catch (const std::runtime_error& error)
  19. {
  20. exception = true;
  21. }
  22. REQUIRE(exception);
  23. //REQUIRE(narrow_cast<long&>(k) == 15);
  24. //REQUIRE(narrow_cast<long&>(i) == 10);
  25. }

测试可知,在转化的类型可以容纳时,narrow_cast可以正常运行,如果narrow_cast转化后的值与原值不同时,会抛出runtime_error的异常。

C++ Programming Language中的narrow_cast实现的更多相关文章

  1. C++ Programming Language中的Calculator源代码

    C++ Programming Language 4th中的Calculator源代码整理,因为在C++ Programming Language中,涉及了很多文件位置之类的变化,所以,这里只是其中的 ...

  2. 编程提取字符串"Java is a programming language"中的各个单词,并打印输出。

    import java.lang.String; import java.util.StringTokenizer; public class StringGetWord{ /* 编程提取字符串&qu ...

  3. iOS Swift-元组tuples(The Swift Programming Language)

    iOS Swift-元组tuples(The Swift Programming Language) 什么是元组? 元组(tuples)是把多个值组合成一个复合值,元组内的值可以使任意类型,并不要求是 ...

  4. iOS Swift-控制流(The Swift Programming Language)

    iOS Swift-控制流(The Swift Programming Language) for-in 在Swift中for循环我们可以省略传统oc笨拙的条件和循环变量的括号,但是语句体的大括号使我 ...

  5. The Swift Programming Language 中文翻译版(个人翻新随时跟新)

    The Swift Programming Language --lkvt 本人在2014年6月3日(北京时间)凌晨起来通过网络观看2014年WWDC 苹果公司的发布会有iOS8以及OS X 10.1 ...

  6. [iOS翻译]《The Swift Programming Language》系列:Welcome to Swift-01

    注:CocoaChina翻译小组已着手此书及相关资料的翻译,楼主也加入了,多人协作后的完整译本将很快让大家看到. 翻译群:291864979,想加入的同学请进此群哦.(本系列不再更新,但协作翻译的进度 ...

  7. the C programming language 阅读笔记1

    读了一遍著名的<the C programming language>,果然如听说的一样,讲解基础透彻,案例简单典型,确实自己C语言还有很多细节点不是很清楚. 总结一下阅读的收获(部分原书 ...

  8. Introduction to OOC Programming Language

    Introduction to OOC Programming Language 文/akisann @ cnblogs.com / zhaihj @ github.com 本文同时发布在github ...

  9. 不忘初心 --- 重读<<The C Programming Language>>

    这篇文章应该发布在好几年前,2011年计算机界大师Dennis Ritchie仙逝,那时对大师的映象还停留在大一刚学编程时:Unix的合作开发者,C语言的发明人.通过网上的纪念文章<<Un ...

随机推荐

  1. servlet_filter简介

    Filter总结: 1.Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静 ...

  2. PHP+ffmpeg+nginx的配置实现视频转码

    最近项目中需要实现上传视频过程中自动转码MP4格式的功能,想到了用FFmpeg来实现它,但从来没有操作过,查阅了很多资料,遇到了好多问题,现在终于安装成功,觉得应该写下来与人分享一下,以免有人遇到和我 ...

  3. python操作redis集群

    strictRedis对象方法用于连接redis 指定主机地址,port与服务器连接,默认db是0,redis默认数据库有16个,在配置文件中指定database 16 上代码 .对redis的单实例 ...

  4. mysql-8.0.12-winx64 解压版安装(转)

    1.官网下载 https://dev.mysql.com/downloads/mysql/ 2.解压到一个合适的目录 3.配置环境变量 path : bin的目录(必须配置) MYSQL_HOME:m ...

  5. spring对bean的高级装配之profile机制

    最近在读spring实战一书,个人感觉内容通俗易懂,学到了一些之前并不知道的知识,于是打算在博客里记录一下这些知识点便于后期记忆: 今天要记录的就是spring的条件化创建bean,针对条件化创建be ...

  6. less 查看日志

    上下键,空格下一页,字母B上一页  ,字母Q退出,n(小写字母n)上一个关键字位置N(大写字母N)下一个关键词位置] 二.查找某个时间段的日志:比如查询2018-08-15 10:37:32到2018 ...

  7. tp5 Excel导入

    /** * 导入Excel功能 */ public function import(){ if (!empty($_FILES)) { $file = request()->file('impo ...

  8. 剑指Offer 13. 调整数组顺序使奇数位于偶数前面 (数组)

    题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 题目地址 https ...

  9. ASP.NET中出现内存溢出错误System.OutOfMemoryException

    原因1:数据库服务器性能问题导致内存不够用,从而引起内存溢出 原因2:在IIS的应用程序池中进行配置,引起IIS服务器的内存分配问题,从而引起内存溢出   分析:      32位操作系统的寻址空间是 ...

  10. JAVA高级篇(四、JVM垃圾回收和调优)

    本文转自https://zhuanlan.zhihu.com/p/25539690 JVM GC(垃圾回收机制) 在学习Java GC 之前,我们需要记住一个单词:stop-the-world .它会 ...