Boost logo

Boost :

Subject: Re: [boost] An extension to boost::variant
From: Chandrashekhar Kumar (iitk.cs_at_[hidden])
Date: 2009-02-09 14:03:03


>
> >> ..My question is this: why can't boost::variant be clever about
> reference
> >> data types..

To quote from the documentation of boost::variant:

http://www.boost.org/doc/libs/1_38_0/doc/html/variant/reference.html#variant.concepts

Every type specified as a template argument to
variant<http://www.boost.org/doc/libs/1_38_0/doc/html/boost/variant.html>must
at minimum fulfill the above requirements. In addition, certain
features of variant are available only if its bounded types meet the
requirements of these following additional concepts:

   - Assignable<http://www.boost.org/doc/libs/1_38_0/doc/html/Assignable.html>:
   variant is itself *Assignable* if and only if every one of its bounded
   types meets the requirements of the concept. (Note that top-level
const-qualified
   types and reference types do *not* meet these requirements.)

So, boost::variant can not handle simple references by design(we will
discuss about the rational behind it soon once I have understood your
requirements more clearly).

Though if you insist on some way out with your intended usage sematics, then
let me think based on my understanding of your requirement so far.

>
> > An example will be better than a lengthy explanation,
> > please have a look at the test-cases in the boost distribution:
> > libs/variant/test/:
> > specially variant_reference_test.cpp
> >
> > IMHO, it will answer all your queries.
>

>
> Hmm... that doesn't seem to answer my question. boost::variant
> currently can not handle the following code:
>
> struct foo {};
>
> int main(int argc, const char** argv)
> {
> foo f;
> foo* pf = &f;
>
> boost::variant<foo*,foo&> v;
>
> v = f;

This is an error, because the declaration of variant above doesn't expect
type of foo.

So, probably you want to write:

    boost::variant < foo, foo *, foo & > v; //extra indentation for better
readability.
then, v = f;

Hold on, this is still not allowed :). I know this is what you want to know
why!

So, you have to find a way to first get the job done then we may discuss the
rest of why!

Quoting from Boost.Ref :
http://www.boost.org/doc/libs/1_38_0/doc/html/ref.html:

"The Ref library is a small library that is useful for passing references to
function templates (algorithms) that would usually take copies of their
arguments."

So, you would like to write instead :

boost::variant<foo, foo*, boost::reference_wrapper<foo> > v;
//<boost/ref.hpp>

Now it is ok.

only then you can write:

    v = f; // now it is fine.

>
> printf("%d\n", &boost::get<foo&>(v) == &f);

The above code is again in error because you have not yet given "foo &" to
your variant.
Though it will be a run-time error(I mean variant will throw an exception
boost::bad_get which you need to catch and gracefully handle n exit from
here)

So, having said this, let me guess again (why I have to do this again.. :-(
) what you want to write instead may be this:

printf("%d\n", &boost::get<foo>(v) == &f);

If you meant it, then I am more confused why you want to do this, knowing
that these 2 addresses can never be equal ??

>
> v = pf;
> printf("%d\n", boost::get<foo*>(v) == pf);
>
> pf = NULL;
> printf("%d\n", boost::get<foo*>(v) != pf)

you have missed a semicolon here :) (did you really try this code on your
machine before posting ? )

Now it looks like everything is fine as per the job in question.

>
>
> return 0;
> }
>
> My question is essentially this: why couldn't it?

Now why?

It is deceitfully simple design decision made by the author.

For now, I will like to quote from
"http://www.boost.org/doc/libs/1_38_0/doc/html/ref/ack.html:

"ref<http://www.boost.org/doc/libs/1_38_0/doc/html/boost/reference_wrapper.html#boost.ref_id2748655>and
cref<http://www.boost.org/doc/libs/1_38_0/doc/html/boost/reference_wrapper.html#boost.cref_id3002915>were
originally part of the
Tuple <http://www.boost.org/doc/libs/1_38_0/libs/tuple/index.html> library
by Jaakko Järvi. They were "promoted to boost:: status" by Peter Dimov
because they are generally useful. Douglas Gregor and Dave Abrahams
contributed is_reference_wrapper<http://www.boost.org/doc/libs/1_38_0/doc/html/boost/is_reference_wrapper.html>and
unwrap_reference<http://www.boost.org/doc/libs/1_38_0/doc/html/boost/unwrap_reference.html>
."

>
>
> Regards,
>
> Chris

HTH for now,

-Cat


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk