boost::variant usage
Asked Answered
W

4

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?

Worcestershire answered 28/3, 2011 at 14:2 Comment(3)
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...Sargassum
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.Fluoroscope
@phooji: thank yout... It is exactly like you have said. I was just confused about name "variant"...Worcestershire
S
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.

Saffron answered 28/3, 2011 at 14:9 Comment(0)
J
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
}
Jaquith answered 28/3, 2011 at 14:17 Comment(3)
A Boost.Variant answer without any mention of static_visitor?Fluoroscope
I know. But it seemed a little beyond the scope of the question.Jaquith
Sadly, boost::variant initialisation and assignment lose their strict type checks when bool is in the mix. (svn.boost.org/trac/boost/ticket/719)Typebar
S
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.

Saffron answered 28/3, 2011 at 14:9 Comment(0)
N
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.

Neurotic answered 28/3, 2011 at 14:8 Comment(0)
U
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<>()...

Unwatched answered 28/3, 2011 at 14:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.