
..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... 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