boost中有一个lexical_cast可以用统一的方式来做基本类型之间的转换,比如字符串到数字,数字到字符串,bool和字符串及数字之间的相互转换。boost::lexical_cast的用法比较简单:

#include <boost/lexical_cast.hpp>
#include <iostream>
#include <string>
#define ERROR_LEXICAL_CAST 1
int main()
{
using boost::lexical_cast;
int a = ;
double b = 0.0;
std::string s = "";
int e = ;
try
{
// ----- 字符串 --> 数值
a = lexical_cast<int>("");
b = lexical_cast<double>("123.12");
// ----- 数值 --> 字符串
s = lexical_cast<std::string>("123456.7");
// ----- 异常处理演示
e = lexical_cast<int>("abc");
}
catch(boost::bad_lexical_cast& e)
{
// bad lexical cast: source type value could not be interpreted as target
std::cout << e.what() << std::endl;
return ERROR_LEXICAL_CAST;
} std::cout << a << std::endl; // 输出:123
std::cout << b << std::endl; // 输出:123.12
std::cout << s << std::endl; // 输出:123456.7
return ;
}

  c++11中缺少lexical_cast方法,但是c++11已经提供了一些基本类型转换的方法,比如to_string, atoi, atof等等,但是我们不能通过一种通用的方式来做基本类型转换,因此我希望做一个类似boost的lexical_cast做基本类型的转换,这也是我们的c++社区的一个开发计划

  由于c++11已经提供了一些便利的方法,我要做的事情就变得很简单了,就是把他们糅合在一起并提供一个统一的lexical_cast的方法即可。

  实现思路也很简单,转换主要有这几种:1.数字到字符串的转换;2.字符串到数字的转换;3.bool与字符串的相互转换;4.数字转换为bool;具体的实现代码如下:

#include <type_traits>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <stdexcept>
#include <cctype>
#include <cstring>
using namespace std; namespace detail
{
const char* strue = "true";
const char* sfalse = "false"; template <typename To, typename From>
struct Converter
{
}; //to numeric
template <typename From>
struct Converter<int, From>
{
static int convert(const From& from)
{
return std::atoi(from);
}
}; template <typename From>
struct Converter<long, From>
{
static long convert(const From& from)
{
return std::atol(from);
}
}; template <typename From>
struct Converter<long long, From>
{
static long long convert(const From& from)
{
return std::atoll(from);
}
}; template <typename From>
struct Converter<double, From>
{
static double convert(const From& from)
{
return std::atof(from);
}
}; template <typename From>
struct Converter<float, From>
{
static float convert(const From& from)
{
return (float)std::atof(from);
}
}; //to bool
template <typename From>
struct Converter<bool, From>
{
static typename std::enable_if<std::is_integral<From>::value, bool>::type convert(From from)
{
return !!from;
}
}; bool checkbool(const char* from, const size_t len, const char* s)
{
for (size_t i = ; i < len; i++)
{
if (from[i] != s[i])
{
return false;
}
} return true;
} static bool convert(const char* from)
{
const unsigned int len = strlen(from);
if (len != && len != )
throw std::invalid_argument("argument is invalid"); bool r = true;
if (len == )
{
r = checkbool(from, len, strue); if (r)
return true;
}
else
{
r = checkbool(from, len, sfalse); if (r)
return false;
} throw std::invalid_argument("argument is invalid");
} template <>
struct Converter<bool, string>
{
static bool convert(const string& from)
{
return detail::convert(from.c_str());
}
}; template <>
struct Converter<bool, const char*>
{
static bool convert(const char* from)
{
return detail::convert(from);
}
}; template <>
struct Converter<bool, char*>
{
static bool convert(char* from)
{
return detail::convert(from);
}
}; template <unsigned N>
struct Converter<bool, const char[N]>
{
static bool convert(const char(&from)[N])
{
return detail::convert(from);
}
}; template <unsigned N>
struct Converter<bool, char[N]>
{
static bool convert(const char(&from)[N])
{
return detail::convert(from);
}
}; //to string
template <typename From>
struct Converter<string, From>
{
static string convert(const From& from)
{
return std::to_string(from);
}
};
} template <typename To, typename From>
typename std::enable_if<!std::is_same<To, From>::value, To>::type lexical_cast(const From& from)
{
return detail::Converter<To, From>::convert(from);
} template <typename To, typename From>
typename std::enable_if<std::is_same<To, From>::value, To>::type lexical_cast(const From& from)
{
return from;
}

前后花了一个多小时,一个基本的类型转换类就完成了,再测试一下吧,测试代码:

void test()
{
cout<<lexical_cast<int>()<<endl;
cout << lexical_cast<int>("") << endl;
cout << lexical_cast<long>("") << endl;
cout << lexical_cast<string>() << endl;
cout << lexical_cast<bool>() << endl;
cout << lexical_cast<double>("1.2") << endl;
cout << lexical_cast<float>("1.2") << endl;
string s = "true";
cout << lexical_cast<bool>(s) << endl;
char* p = "false";
cout << lexical_cast<bool>(p) << endl;
const char* q = "false";
cout << lexical_cast<bool>(q) << endl;
cout << lexical_cast<bool>("false") << endl;
cout << lexical_cast<bool>("test") << endl;
} int main()
{
try
{
test();
}
catch (const std::exception& e)
{
cout << e.what() << endl;
} return ;
}

测试结果:

c++11实现一个简单的lexical_cast的更多相关文章

  1. django学习-11.开发一个简单的醉得意菜单和人均支付金额查询页面

    1.前言 刚好最近跟技术部门的[产品人员+UI人员+测试人员],组成了一桌可以去公司楼下醉得意餐厅吃饭的小team. 所以为了实现这些主要点餐功能: 提高每天中午点餐效率,把点餐时间由20分钟优化为1 ...

  2. 构建一个简单的Spring Boot项目

    11 构建一个简单的Spring Boot项目 这个章节描述如何通过Spring Boot构建一个"Hello Word"web应用,侧重介绍Spring Boot的一些重要功能. ...

  3. 一个简单的SpringBoot入门程序

    1. 使用IDEA构建Maven项目 <?xml version="1.0" encoding="UTF-8"?> <project xmln ...

  4. Java学习笔记 11/15:一个简单的JAVA例子

    首先来看一个简单的 Java 程序. 来看下面这个程序,试试看是否看得出它是在做哪些事情! 范例:TestJava.java   // TestJava.java,java 的简单范例  public ...

  5. 使用MongoDB和JSP实现一个简单的购物车系统

    目录 1 问题描述  2 解决方案  2.1  实现功能  2.2  最终运行效果图  2.3  系统功能框架示意图  2.4  有关MongoDB简介及系统环境配置  2.5  核心功能代码讲解  ...

  6. 《Entity Framework 6 Recipes》翻译系列 (3) -----第二章 实体数据建模基础之创建一个简单的模型

    第二章 实体数据建模基础 很有可能,你才开始探索实体框架,你可能会问“我们怎么开始?”,如果你真是这样的话,那么本章就是一个很好的开始.如果不是,你已经建模,并在实体分裂和继承方面感觉良好,那么你可以 ...

  7. 通过Knockout.js + ASP.NET Web API构建一个简单的CRUD应用

    REFERENCE FROM : http://www.cnblogs.com/artech/archive/2012/07/04/Knockout-web-api.html 较之面向最终消费者的网站 ...

  8. 如何创建一个简单的C++同步锁框架(译)

    翻译自codeproject上面的一篇文章,题目是:如何创建一个简单的c++同步锁框架 目录 介绍 背景 临界区 & 互斥 & 信号 临界区 互斥 信号 更多信息 建立锁框架的目的 B ...

  9. 利用ANTLR4实现一个简单的四则运算计算器

    利用ANTLR4实现一个简单的四则运算计算器 ANTLR4介绍 ANTLR能够自动地帮助你完成词法分析和语法分析的工作, 免去了手写去写词法分析器和语法分析器的麻烦 它是基于LL(k)的, 以递归下降 ...

随机推荐

  1. 一些有用的git命令清单

    以下是一些我常用的git命令清单 如果以下的命令不清晰细节,请看git的文档. 设置个人信息 git config --global user.name "John Doe" gi ...

  2. libev ev_io_init学习

    #define ev_io_init(ev,cb,fd,events) / do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } w ...

  3. POJ 2296 Map Labeler (2-Sat)

    Map Labeler Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1267   Accepted: 409 Descri ...

  4. 部署hadoop的开发环境

    第一步:安装jdk 由于hadoop是java开发的,所以需要JDK来运行代码.这里安装的是jdk1.6. jdk的安装见http://www.cnblogs.com/tommyli/archive/ ...

  5. 【IL】IL指令详解

    名称 说明 Add 将两个值相加并将结果推送到计算堆栈上. Add.Ovf 将两个整数相加,执行溢出检查,并且将结果推送到计算堆栈上. Add.Ovf.Un 将两个无符号整数值相加,执行溢出检查,并且 ...

  6. java 发送post请求参数中含有+会转化为空格的问题

    如题 原因分析:参数在传递过程中经历的几次编码和解码标准不同,导致加号.空格等字符的错误. 解决方案:将post请求的参数中 ,含有+号的,统统采用%2B 去替换,这是URL的协议问题.

  7. Windows 重装系统-用户转移User和Program Files 文件夹

    原文地址:https://blog.csdn.net/sinat_38799924/article/details/74059037 重装系统时为了让系统数据保持可用我们需要做一些备份处理.比如用户数 ...

  8. Spring-Boot服务注册与发现

    关于Eureka服务注册与发现的示例可以参见:http://blog.didispace.com/springcloud1/ 服务注册管理器原理如下图所示: 1.建立eureka服务器 @Enable ...

  9. mmap映射文件至内存( 实现 共享内存 与 文件的另类访问 )

    Linux提供了内存映射函数mmap, 它把文件内容映射到一段内存上(准确说是虚拟内存上), 通过对这段内存的读取和修改, 实现对文件的读取和修改, 先来看一下mmap的函数声明: 头文件: < ...

  10. 使用Python3自带工具2to3.py 转换 Python2.x 代码 到Python3

    几乎所有的Python 2程序都需要一些修改才能正常地运行在Python 3的环境下.为了简化这个转换过程,Python 3自带了一个叫做2to3的实用脚本(Utility Script),这个脚本会 ...