C ++ 11 implements a simple lexical_cast, and 11 implements lexical_cast.

Source: Internet
Author: User
Tags string to number

C ++ 11 implements a simple lexical_cast, and 11 implements lexical_cast.

There is a lexical_cast in boost that can be used for conversion between basic types in a unified manner, such as conversion between strings to numbers, numbers to strings, bool, and strings and numbers. Boost: lexical_cast is easy to use:

# Include <boost/lexical_cast.hpp> # include <iostream> # include <string> # define ERROR_LEXICAL_CAST 1 int main () {using boost: lexical_cast; int a = 0; double B = 0.0; std: string s = ""; int e = 0; try {// ----- string --> value a = lexical_cast <int> ("123 "); B = lexical_cast <double> ("123.12"); // ----- value --> string s = lexical_cast <std: string> ("123456.7 "); // ----- Exception Handling demo e = lexical_cast <int> ("abc");} catch (boost: bad_lexical_cast & e) {// bad lexical cast: source type value cocould not be interpreted as target std: cout <e. what () <std: endl; return ERROR_LEXICAL_CAST;} std: cout <a <std: endl; // output: 123 std :: cout <B <std: endl; // output: 123.12 std: cout <s <std: endl; // output: 123456.7 return 0 ;}View Code

The lexical_cast method is missing in c ++ 11, but c ++ 11 provides some basic type conversion methods, such as to_string, atoi, atof, etc, however, we cannot use a common method to convert the basic types. Therefore, I want to convert the basic types by using lexical_cast similar to boost, this is also a development plan for our c ++ community.

Since c ++ 11 has provided some convenient methods, what I want to do is to combine them and provide a unified lexical_cast method.

The implementation idea is also very simple. There are mainly the following types of conversions: 1. number to String Conversion; 2. string to number conversion; 3. convert bool and string; 4. convert a number to bool. The specific implementation code is as follows:

#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 = 0; 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 != 4 && len != 5)            throw std::invalid_argument("argument is invalid");        bool r = true;        if (len == 4)        {            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;}

It took more than an hour before and after, and a basic type conversion class was completed. Test the code again:

void test(){    cout<<lexical_cast<int>(1)<<endl;    cout << lexical_cast<int>("1") << endl;    cout << lexical_cast<long>("1") << endl;    cout << lexical_cast<string>(1) << endl;    cout << lexical_cast<bool>(1) << 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 0;}

Test results:

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.