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)的, 以递归下降 ...
随机推荐
- 【jsPDF】jsPDF插件实现将html页面转换成PDF,并下载,支持分页
1.目的:在前段是 jQuery库 或者 VUE库 或者两者混合库,将html 页面和数据 转换成PDF格式并下载,支持分页 1.项目背景: 对客户报修记录进行分类统计,并生成各种饼图.柱状图.线性图 ...
- Effective Tensorflow[转]
Effective TensorFlow Table of Contents TensorFlow Basics Understanding static and dynamic shapes Sco ...
- apache安装mod_ssl.so 出现 undefined symbol: ssl_cmd_SSLPassPhraseDialog错误解决
很久很久以前,安装Apache的时候,根本没想过将来的某一天会使用到ssl,所以也就没有安装那个模块,结果今天需要用到的时候,却无从下手了. 由于在安装Apache的时候,mod_ssl.so这个文件 ...
- IOC 之深入理解 Spring IoC
在一开始学习 Spring 的时候,我们就接触 IoC 了,作为 Spring 第一个最核心的概念,我们在解读它源码之前一定需要对其有深入的认识,本篇为[死磕 Spring]系列博客的第一篇博文,主要 ...
- 记录EntityValidationErrors的详细信息
0.一个问题 使用过EF的人相信都会遇到Validation failed for one or more entities. See ‘EntityValidationErrors’这种异常,这是由 ...
- Git 远程仓库(分布式版本控制系统)
前言 远程仓库是指托管在因特网或其他网络中的你的项目的版本库.你可以有好几个远程仓库,通常有些仓库对你只读,有些则可以读写. 1.查看远程仓库 如果想查看你已经配置的远程仓库服务器,可以运行 git ...
- 【转】Google 的眼光
Google 的眼光 你知道吗,Google(Alphabet)要卖掉 Boston Dynamics,一个它收购才没多久的机器人公司.这也意味着,Google 准备完全退出机器人的领域.新闻传言说, ...
- C#文件下载(实现断点续传)
public class WebDown { /// 下载文件方法 /// 文件保存路径和文件名 /// 返回服务器文件名 public static bool DeownloadFile(strin ...
- 【转载】Hibernate之hbm.xml集合映射的使用(Set集合映射,list集合映射,Map集合映射)
https://www.cnblogs.com/biehongli/p/6555994.html
- A标签href属性详解--记录八
1.去掉<a>标签的下划线 <ul style=" list-style-type:none; margin:0;color:Gray; font-size:11px;ma ...