Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) LexicalCast

 

LexicalCast is a convert code snippet to convert std::string to (possibly) any data type. CanCast can check if this conversion is possible.

 

LexicalCast uses CanCast.

 

LexicalCast serves the same purpose as boost::lexical_cast, but does not use Boost. Note that there are differences between LexicalCast and boost::lexical_cast, as boost::lexical_cast is more strict.

 

#include <string>
#include <cassert>

//From http://www.richelbilderbeek.nl/CppLexicalCast.htm
template <typename TargetType>
const TargetType LexicalCast(const std::string& s);

//From http://www.richelbilderbeek.nl/CppLexicalCast.htm
template <>
const int LexicalCast<int>(const std::string& s)
{
  assert(CanCast<int>(s) == true);
  return std::atoi(s.c_str());
}

//From http://www.richelbilderbeek.nl/CppLexicalCast.htm
template <>
const double LexicalCast<double>(const std::string& s)
{
  assert(CanCast<double>(s) == true);
  return std::atof(s.c_str());
}

 

 

 

 

 

Comparison between LexicalCast and boost::lexical_cast

 

The table below shows if a std::string can be converted according to CanCast (CC) and CanLexicalCast (CLC) and what the result will be after LexicalCast (LC) and boost::lexical_cast (l_c). Note that the first std::string was a space (' '). Below the table I show the code I've used to generate this output.

 

*******************************************************************************
Testing CanCast and LexicalCast
*******************************************************************************
std:: CC? LC CC? LC
string int int double double
false ... false ...
a false ... false ...
1 true 1 true 1
1. true 1 true 1
1.1 true 1 true 1.1
1.1. true 1 true 1.1
1.1.1 true 1 true 1.1
1a true 1 true 1
1.1a true 1 true 1.1
-1 true -1 true -1
-1. true -1 true -1
-1.1 true -1 true -1.1
-1.1. true -1 true -1.1
-1.1.1 true -1 true -1.1
*******************************************************************************
Testing CanLexicalCast and boost::lexical_cast
*******************************************************************************
std:: CLC? l_c CLC? l_c
string int int double double
false ... false ...
a false ... false ...
1 true 1 true 1
1. false ... true 1
1.1 false ... true 1.1
1.1. false ... false ...
1.1.1 false ... false ...
1a false ... false ...
1.1a false ... false ...
-1 true -1 true -1
-1. false ... true -1
-1.1 false ... true -1.1
-1.1. false ... false ...
-1.1.1 false ... false ...

 

const std::vector<std::string> GetTests()
{
  std::vector<std::string> v;
  v.push_back(" ");
  v.push_back("a");
  v.push_back("1");
  v.push_back("1.");
  v.push_back("1.1");
  v.push_back("1.1.");
  v.push_back("1.1.1");
  v.push_back("1a");
  v.push_back("1.1a");
  v.push_back("-1");
  v.push_back("-1.");
  v.push_back("-1.1");
  v.push_back("-1.1.");
  v.push_back("-1.1.1");
  return v;
}

int main()
{
  const std::vector<std::string> v = GetTests();

  const int size = v.size();

  std::cout << std::string(79,'*') << std::endl;
  std::cout << "Testing CanCast and LexicalCast" << std::endl;
  std::cout << std::string(79,'*') << std::endl;
  {
    std::cout << "std::" << '\t'
      << "CC?" << '\t' << "LC" << '\t'
        << "CC?" << '\t' << "LC"
      << std::endl;
    std::cout << "string" << '\t'
      << "int" << '\t' << "int" << '\t'
      << "double" << '\t' << "double"
      << std::endl;

    for (int i=0; i!=size; ++i)
    {
    const std::string s = v[i];
    std::cout << s << '\t';
    if (CanCast<int>(s) == true)
    {
      std::cout << "true" << '\t' << LexicalCast<int>(s) << '\t';
    }
    else
    {
      std::cout << "false" << '\t' << "..." << '\t';
    }
    if (CanCast<double>(s) == true)
    {
      std::cout << "true" << '\t' << LexicalCast<double>(s) << '\t';
    }
    else
    {
      std::cout << "false" << '\t' << "..." << '\t';
    }
    std::cout << std::endl;
    }
  }

  std::cout << std::string(79,'*') << std::endl;
  std::cout << "Testing CanLexicalCast and boost::lexical_cast" << std::endl;
  std::cout << std::string(79,'*') << std::endl;
  {
    std::cout << "std::" << '\t'
    << "CLC?" << '\t' << "l_c" << '\t'
    << "CLC?" << '\t' << "l_c"
    << std::endl;
    std::cout << "string" << '\t'
    << "int" << '\t' << "int" << '\t'
    << "double" << '\t' << "double"
    << std::endl;
  
    for (int i=0; i!=size; ++i)
    {
      const std::string s = v[i];
      std::cout << s << '\t';
      if (CanLexicalCast<int>(s) == true)
      {
        std::cout << "true" << '\t' << boost::lexical_cast<int>(s) << '\t';
      }
      else
      {
        std::cout << "false" << '\t' << "..." << '\t';
      }
      if (CanLexicalCast<double>(s) == true)
      {
        std::cout << "true" << '\t' << boost::lexical_cast<double>(s) << '\t';
      }
      else
      {
        std::cout << "false" << '\t' << "..." << '\t';
      }
      std::cout << std::endl;
    }
  }
}

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict