仿照boost::lexical_cast,编写一个text_cast

2024-01-18 04:48

本文主要是介绍仿照boost::lexical_cast,编写一个text_cast,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先说明,这个text_cast不光是编写来玩的,它还有一定的用途。我在最近的一个跨平台(Win32,数个版本的Linux)的项目中用到了boost库,编码的时候还是很爽的,等到了移植的时候,就发现我每到一个平台(数量还在增加)上,就要先把boost编译一下,如果光是这样倒也罢了。更要命的是我发现boost在某些平台上的表现有微妙的差别,例如在异常的处理上,这些给我带来了不少麻烦。在很多次痛苦的追踪以后,发现问题竟然追到了boost库里面!不是说boost不好,而是它设计的太通用,而我的很多要求都很简单。经过一番思索,我发现我其实只用了boost的date_time库和lexical_cast,所以痛定思痛,决定干脆还是自己把这两个功能实现了算了,虽然效率可能没有boost来得高,稳定性可能没有boost好,但是只要能应付我的需求就是好的。

首先是取代lexical_cast的工作,lexical_cast在我的应用中都是这样出现的——
把string转换成原生类型:
int i = lexical_cast ("234");
把原生类型转换成string:
string s = lexical_cast (true);

如果自己写一个text_cast,首要的要求就是尽可能少的改动客户代码,也就是说,最好用一个replace就能完成改动工作,那么就要保证调用语法和语义都与lexical_cast一致。入手当然很容易:

template
Target text_cast(const string& arg)
{
  stringstream ss(arg);
  Target ret;
  ss >> ret;

  return ret;
}

仅仅使用它,把string转换成原生类型都没有问题了,但是它不能把原生类型转换成string。因为它压根儿就不接受这些参数。那么,我们再加一个可不可以呢?

template
string text_cast(Source arg)
{
  stringstream ss;
  ss << arg;

  return ss.str(); 
}


使用这两个模版,当我们用下面的代码来测试的时候,VC7.1会抱怨的

int main()
{
  string str = "234";
  int i = text_cast (str);
  cout << i << endl;

  string s = text_cast (i);
  cout << s << endl;
}

错误信息是:
error C2665: “text_cast” : 2 个重载中没有一个可以转换参数 1(从“int”类型)
        c:/boosttest/boosttest.cpp(8): 可能是“std::string text_cast (Source)”
        with
        [
            Source=std::string
        ]
        c:/boosttest/boosttest.cpp(17): 或       “Target text_cast (const std::string &)”
        with
        [
            Target=std::string
        ]
        试图匹配参数列表“(int)”时

道理很简单,正如提示所说,对于text_cast (i),编译器不知道如何去匹配正确的函数。如果把这一句改为 text_cast(i) ,换言之,不用模版参数,让编译器自己去匹配,倒是可以通过。但是这样就要改动客户代码,怎么办呢?其实可以这样解决:

template
string text_cast(Source arg)
{
  stringstream ss;
  ss << arg;

  return ss.str(); 
}

这样做的结果是使得

template
Target text_cast(const string& arg)


成了这个模版的偏特化版本,在参数类型为string的时候,会调用后者,而其他的时候(当然这个时候目标类型就是string了)会调用前者。这样,上面的程序段就可以顺利地通过了。
其实还有一个问题,上面的两个模版在把string转换成bool的时候,不能符合我的要求。我希望它能把字符串true, True, t, T, 1以及种种古怪的形式变成bool类型的true,而把false, False, f, F, 0等等的变成bool类型的false。而stringstream只有在看到0和1的时候才能正确的工作。于是,又需要编写一个针对bool类型的偏特化版本:

template<>
bool text_cast(const string& arg)
{
  char c = arg[0];
  if(c == '1' || c == 't' || c == 'T')
    return true;
  else if(c == '0' || c == 'f' || c == 'F')
    return false;
  else
    throw;
  // 当然,这里的处理还应该更系统一点
}


这样,即便 text_cast ("tRuE") 这样的调用也难不倒它。虽然它可能把 "tttt" 也转换成true,但是在我的程序里面,不会有这样的情况发生。





这篇关于仿照boost::lexical_cast,编写一个text_cast的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/618108

相关文章

如何编写Linux PCIe设备驱动器 之二

如何编写Linux PCIe设备驱动器 之二 功能(capability)集功能(capability)APIs通过pci_bus_read_config完成功能存取功能APIs参数pos常量值PCI功能结构 PCI功能IDMSI功能电源功率管理功能 功能(capability)集 功能(capability)APIs int pcie_capability_read_wo

【Python报错已解决】AttributeError: ‘list‘ object has no attribute ‘text‘

🎬 鸽芷咕:个人主页  🔥 个人专栏: 《C++干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言一、问题描述1.1 报错示例1.2 报错分析1.3 解决思路 二、解决方法2.1 方法一:检查属性名2.2 步骤二:访问列表元素的属性 三、其他解决方法四、总结 前言 在Python编程中,属性错误(At

Wondows dos下怎么编写bat批处理文件

最近搞php,在运行时,以Nginx+php-cgi.exe方式运行Wordpress项目 打开dos,先cd到php-cgi.exe文件当前目录下执行启动命令:php-cgi.exe -b 127.0.0.1:9001再打开一个dos,再cd到nginx.exe文件当前目录下执行启动命令:start nginx 大概过程要经过这些步骤,觉得很麻烦,就学下怎么编写一个bat文件,以双击运行代替

用Python编写倒计时程序:详细教程

目录 引言 环境准备 基本概念 代码实现 步骤一:导入必要的库 步骤二:获取用户输入 步骤三:实现倒计时逻辑 步骤四:整合代码 运行程序 高级功能 扩展功能示例:支持分钟和小时输入 扩展功能示例:图形用户界面 (GUI) 总结 引言 倒计时程序是一个非常常见的小工具,广泛用于各种应用场景中,例如考试时间提醒、烹饪计时器、会议倒计时等。Python 作为一种

Boost程序库入门学习

优秀的程序员要能够知其所以然,而不是重复的造轮子,近期目标是学习优秀的第三方库,同时尝试使用C++11/14新特性,然后吸取精华用到项目中去,加油~ 参考书籍: 罗剑锋写的《Boost程序库完全开发指南》和《Boost程序库探秘》,前者是一个大体的介绍,后者是针对一些诸如模板元编程等高级特性做了深入的探讨。 一、Boost库概述 Boost是一个功能强大、构造精巧、跨平台、开源并且完全

【ReactJS】困惑于text/babel与browser.js还是babel.js?

使用JSX   使用JSX,可以极大的简化React元素的创建,JSX抽象化了React.createElement()函数的使用,其语法风格类似于HTML语法风格。对比如下代码可以让你更好的理解这一点。 // 使用React.createElement()return React.createElement('div',null,'Hello',this.props.name);//使用J

【Spring boot】编写代码及测试用例入门之 Hello Spring boot _踩坑记

先贴下目录: 这是我从 start.spring.io 里下载的依赖Web的模板 // DemoApplication.javapackage com.abloume.springboot.blog.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autocon

windows下使用vscode编写运行以及调试C/C++

vscode支持类似于vs的断点调试c/c++,也可以直接编译&运行c/c++ 先是编译运行 c/c++的方法                              微软官方起初设定的科学做法(这也是现在的科学做法)是通过在vscode集成控制台写命令行的方式来实现编译运行程序的,但也可以通过code runner插件来简化步骤,实现一键编译执行 但无论是什么方法,因为vscod

Python编写简单登录系统的完整指南

在现代应用中,用户认证和登录系统是一个非常重要的功能。通过登录系统,应用能够识别用户的身份,并为其提供相应的权限和服务。本文将介绍如何使用Python编写一个简单的登录系统,包括用户注册、登录验证、密码加密等功能。通过这一教程,将学习如何构建一个基本的用户登录系统,并理解其中的关键技术。 这里插播一条粉丝福利,如果你在学习Python或者有计划学习Python,想在未来人工智能领域吃上一口饭的,

springboot项目编写发送异常日志到企微工具包

1.创建基础Bean public final class ThreadFactory implements java.util.concurrent.ThreadFactory {private static final AtomicInteger poolNumber = new AtomicInteger(1);private final ThreadGroup group;priva