c++11实现一个简单的lexical_cast
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的更多相关文章
- django学习-11.开发一个简单的醉得意菜单和人均支付金额查询页面
1.前言 刚好最近跟技术部门的[产品人员+UI人员+测试人员],组成了一桌可以去公司楼下醉得意餐厅吃饭的小team. 所以为了实现这些主要点餐功能: 提高每天中午点餐效率,把点餐时间由20分钟优化为1 ...
- 构建一个简单的Spring Boot项目
11 构建一个简单的Spring Boot项目 这个章节描述如何通过Spring Boot构建一个"Hello Word"web应用,侧重介绍Spring Boot的一些重要功能. ...
- 一个简单的SpringBoot入门程序
1. 使用IDEA构建Maven项目 <?xml version="1.0" encoding="UTF-8"?> <project xmln ...
- Java学习笔记 11/15:一个简单的JAVA例子
首先来看一个简单的 Java 程序. 来看下面这个程序,试试看是否看得出它是在做哪些事情! 范例:TestJava.java // TestJava.java,java 的简单范例 public ...
- 使用MongoDB和JSP实现一个简单的购物车系统
目录 1 问题描述 2 解决方案 2.1 实现功能 2.2 最终运行效果图 2.3 系统功能框架示意图 2.4 有关MongoDB简介及系统环境配置 2.5 核心功能代码讲解 ...
- 《Entity Framework 6 Recipes》翻译系列 (3) -----第二章 实体数据建模基础之创建一个简单的模型
第二章 实体数据建模基础 很有可能,你才开始探索实体框架,你可能会问“我们怎么开始?”,如果你真是这样的话,那么本章就是一个很好的开始.如果不是,你已经建模,并在实体分裂和继承方面感觉良好,那么你可以 ...
- 通过Knockout.js + ASP.NET Web API构建一个简单的CRUD应用
REFERENCE FROM : http://www.cnblogs.com/artech/archive/2012/07/04/Knockout-web-api.html 较之面向最终消费者的网站 ...
- 如何创建一个简单的C++同步锁框架(译)
翻译自codeproject上面的一篇文章,题目是:如何创建一个简单的c++同步锁框架 目录 介绍 背景 临界区 & 互斥 & 信号 临界区 互斥 信号 更多信息 建立锁框架的目的 B ...
- 利用ANTLR4实现一个简单的四则运算计算器
利用ANTLR4实现一个简单的四则运算计算器 ANTLR4介绍 ANTLR能够自动地帮助你完成词法分析和语法分析的工作, 免去了手写去写词法分析器和语法分析器的麻烦 它是基于LL(k)的, 以递归下降 ...
随机推荐
- vmware网络模式仅主机模式linux不能ping通window
问题描述 vmware在使用仅主机模式,新建的linux虚拟机,不能ping通window本机(宿主主机).....(这不蛋疼吗...) 注意:后面的搞定后的结果 解决方案 开启家庭组的,网络发现功能 ...
- Spring Cloud开发实践 - 02 - Eureka服务和接口定义
服务注册 EurekaServer Eureka服务模块只有三个文件, 分别是pom.xml, application.yml 和 EurekaServerApplication.java, 内容如下 ...
- 转:OGRE 渲染通路(Pass)
一个渲染通路就是几何问题里的一次渲染:一个带有一整套渲染属性的渲染API的一次调用.一个技术可以包含有1到16个渲染通路,当然,渲染通路用得越多,技术在渲染的时候开销越大. 为了清楚识别使用的到底是哪 ...
- C#实现多文件上传,写到文件夹中,获取文件信息以及下载文件和删除文件
前台:.js //上传附件 function uploadAttachment() { if ($("#Tipbind").attr('checked')) { var ip = ...
- NYOJ----蛇形填数
蛇形填数 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 在n*n方陈里填入1,2,...,n*n,要求填成蛇形.例如n=4时方陈为: 10 11 12 1 9 16 ...
- GO语言中的几个关键思想
GO语言的设计理念与C++,Java,Python之流大相径庭. 一.没有函数重载 GO语言里面没有函数重载,Java.C#.C++三位大牛都是支持函数重载的,Python虽然不支持函数重载,但是支持 ...
- jenkins+maven+git+ 邮件自动转发 持续化集成 图文教程
1.所需要的插件,安装plugin ,进入mangae Jenkins→ manage Plugins, 切换到Available tab, 选择如下plugin 安装 Gitplugin, GitH ...
- 浅析iOS中的触摸事件
一.什么是响应者对象? 在 iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件.我们称之为“响应者对象”.UIApplication.UIViewControl ...
- 一台电脑存放多个git账户的多个rsa秘钥(转)
如何在一个电脑上存储多个git账户生成的多份rsa秘钥,实现多个账户同时使用配置的情况?今天,不幸又再次遇到这个问题. 问题描述 公司最近在开发一款开源产品,项目被托管在github上,但是公司内部一 ...
- rsync的基本使用
1,本地同步文件: rsync -avz --delete /home/ /backups/ 注意:在指定复制源时,路径是否有最后的 “/” 有不同的含义,例如: /home: 表示将整个 /home ...