8

I am developing GUI application via wxWidgets. It has 2 parts: GUI part and "Logic" part. I want to have Logic part totally independent on wxWidgets. But one component in the GUI returning wxVariant and I need to use it in the Logic part.

So I am looking for a way to "convert" wxVariant to boost::variant

wxVariant works like this:

wxVariant v("37");
int i = v.GetInteger(); //i==37

So I am thinking something like

string s = methodReturningWxVariant().GetString();
boost::variant bV(s);

//later in code e.g
bV.GetInt();
bV.GetBool();

Is it possible to use boost::Variant (or boost::Any) like this?

relaxxx
  • 7,566
  • 8
  • 37
  • 64
  • Unless you need to, why not just use `wxAny`? If need you need to, then consider doing a check on `wxAny` before assigning value to `boost::variant`... – Nim Mar 28 '11 at 14:21
  • Have a closer look at the documentation -- there is no type called `boost::[V/v]ariant` -- it is a template class that needs to know the types in advance. The similarity in name is mostly accidental, in fact, wxWdgets will be replacing wxVariant with wxAny at some point to avoid this. In related news, Boost.Any is a little closer, but it still doesn't let you parse and unparse strings, af far as I know. – phooji Mar 28 '11 at 14:24
  • @phooji: thank yout... It is exactly like you have said. I was just confused about name "variant"... – relaxxx Mar 28 '11 at 18:23

4 Answers4

23

You can probably use boost::variant with some changes. To start with, you need to tell boost::variant which types it will be storing:

boost::variant<int, string, bool> v;

Since you probably will be using this type in a few places, you will probably want to create an alias for it. i.e.

typedef boost::variant<int, string, bool> myvar;

then you can use myvar directly:

myvar x = "hello";
myvar y = 20;
myvar z = false;

to retrieve values:

string s = boost::get<string>(x);
int i = boost::get<int>(y);
bool b = boost::get<bool>(z);

If you attempt to get a different type than is stored in the variant, it will throw an exception.

You can query the variant's type with the which() member function. It will return a 0-based index to the type the variant is currently holding.

switch (x.which()) {
case 0: // it's an int
case 1: // it's a string
case 2: // it's a bool
}
Ferruccio
  • 98,941
  • 38
  • 226
  • 299
4

Simple answer? No. You cannot convert via strings, this induces a loss of information and boost::variant does not automatically attempt to parse strings.

I don’t know whether wxVariant offers an explicit conversion – in general, it may be difficult to convert to boost::variant without testing for special cases.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
1

boost::variant (please don't capitalize 'v') works another way: you can only get back what you put inside. Think about it as a type-safe(r) union.

Checking documenation and tutorial also won't hurt.

Boost.Any library doesn't differ from Boost.Variant in this respect (what you put is what you get :) ), but boost::any is unbounded: you can store value of any type in boost::any, but in boost::variant you can only store what was declared by variant's template parameters.

Alexander Poluektov
  • 7,844
  • 1
  • 28
  • 32
0

boost::variant does not do conversion for you. There are other separate means to convert a string to an integer, such as strtol(), sscanf(), boost::lexical_cast<>()...

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271