boost::variant<T> to std::string
Asked Answered
M

4

9

I have a boost variant of looking like this: typedef boost::variant<int, float, double, long, bool, std::string, boost::posix_time::ptime> variant;

I have a need for being able to convert any of the values in this variant to a std::string, I wondered if there is some template type function I could use to do this?

Or what would be the most effective way?

I would currently implement a bunch of overloaded functions, each taking a type and then doing the conversion using std::stringstream or for posix_time i'd use it's conversion function. Perhaps there is a better way?

Milliemillieme answered 8/12, 2010 at 15:30 Comment(0)
B
10

Use boost::lexical_cast, which hides the whole stringstream thing behind a convenient wrapper. This also works with boost::posix_time, since it has a suitable operator<<.

Beachcomber answered 8/12, 2010 at 15:33 Comment(0)
H
4

Try this:

struct to_string_visitor : boost::static_visitor<>
{
  std::string str; 

  template <typename T>
  void operator()(T const& item)
  {
    str = boost::lexical_cast<std::string>(item);
  }
  void operator()(boost::posix_time::ptime const & item)
  {
    //special handling just for ptime
  }
};

int main(){
  variant v = 34;
  to_string_visitor vis;
  boost::apply_visitor(vis, v);
  cout << vis.str << endl;
}
Hollah answered 8/12, 2010 at 15:51 Comment(2)
Ok, changed. I didn't compiled this.Hollah
Nice one! Powerful usage of overloading.Bruiser
H
1

See generically convert from boost::variant<T> to type. You should be able to adapt that answer to your situation. You can use boost::lexical_cast for all your types except the boost::posix_time::ptime where you probably need to do a special solution. All of this in the static_visitor using operator overloading (template + one for the ptime).

Heinrich answered 8/12, 2010 at 15:39 Comment(0)
J
0

a cleaner and more elegant (but not more efficient) way to convert a certain type into std::string is to use

template<typename Target, typename Source> Target lexical_cast(const Source& arg);

from

#include <boost/lexical_cast.hpp>

The type to be converted needs to provide the usual "<<" operator for ostream.

example usage: std::string s = boost::lexical_cast<std::string>( 17 ); assert( s == "17" );

Jitney answered 8/12, 2010 at 15:42 Comment(1)
Actually it can also be more efficient (boost should use a stack array for the stream buffer if the maximum length of a type's string representation is known at compile-time). But the question was about boost::variant.Halflight

© 2022 - 2024 — McMap. All rights reserved.