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 ;
}

测试结果:

最新文章

  1. BZOJ 2685: Sgu385 highlander
  2. 智能车学习(二十三)&mdash;&mdash;浅谈心得体会
  3. struts2支持的结果类型
  4. 《Qt 实战一二三》
  5. 【Mood-17】 github中在本地进行上传的时候出现ERROR: Repository not found. fatal: The remote end hung up unexpectedly
  6. 再看ADO对象模型
  7. 认识Require
  8. shell与export命令
  9. Activity 之生命周期
  10. Python数据处理PDF
  11. 02.02.03第3章 餐饮项目案例(Power BI商业智能分析)
  12. docker容器与宿主交互数据
  13. pxc5.7配置安装
  14. Java加载dll或so库文件的路径 java.library.path
  15. CF1106F Lunar New Year and a Recursive Sequence 原根、矩阵快速幂、BSGS
  16. SpringMVC在使用Jackson2时关于日期类型格式化的问题
  17. es6(16)--Decorator
  18. c++桥接模式
  19. 进程和创建线程的两种方法(threading.Thread)
  20. 新一代的USB 3.0传输规格

热门文章

  1. Newifi2(D1) 刷入pb-boot和breed的记录
  2. masonry瀑布流的使用
  3. 【laravel5.*】详解laravel中的依赖注入
  4. android如何查看cpu的占用率和内存泄漏
  5. 【CAS单点登录视频教程】 第05集 -- CAS服务器安装
  6. [转]webMethods公司简介
  7. Python字典按值排序的方法
  8. mysql--SQL编程(关于mysql中的日期,关于重叠) 学习笔记2.2
  9. 转载:librdkafka问题总结
  10. ubuntu安装wkhtmltopdf