Hi Alan,
Thanks for the ideas... Here is some feedback.
> On Wed, 2008-10-22 at 19:40 -0400, Steve Huston wrote:
> > Hi Alan,
> >
> > I have a question on this change to qpid/Url.h:
> >
> > --- Url.h (revision 693917)
> > +++ Url.h (revision 693918)
> > @@ -45,7 +45,11 @@
> > std::ostream& operator<<(std::ostream& os, const TcpAddress& a);
> >
> > /** Address is a variant of all address types, more coming
> in future.
> > */
> > -typedef boost::variant<TcpAddress> Address;
> > +struct Address : public boost::variant<TcpAddress> {
> > + template <class T> Address(const T& t) :
> > boost::variant<TcpAddress>(t) {}
> > + template <class T> T* get() { return boost::get<T>(this); }
> > + template <class T> const T* get() const { return
> > boost::get<T>(this); }
> > +};
> >
> > With this change, the Windows Visual C++ 8 compiler chokes.
> Could you
> > elaborate a bit on why the change is there and what may be the
issue
> > here? I've tried adjusting the template types to get around it but
> > have had no success.
>
> The goal was to remove the requirement for explicit reference to the
> boost namespace in user code
In qpid users' code? Is this because Url is exposed in
qpid/client/Connection?
> and to make the Address class more self
> contained. I find a get<T>() member is more intuitive than a get
free
> function.
Right... I'm fairly new to boost variant, but the variant docs make
the case that get() is pretty fragile itself and recommend using
another way to access the variants. (apply_visitor).
> Try the following, it gives better encapsulation for the boost
stuff
> and avoids the inheritance which is probably the cause of the
> convert_construct confusion. I haven't tried to build this so
> apologies
> if I've missed something, I'm sure we can figure out
> something portable
> and now is the time if we need to change the API:
>
> struct Address {
> public:
> Address(const Address& a) : value(a.value) {}
> explicit template <class T> Address(const T& t) : value(t) {}
> template <class T> Address& operator=(const T& t) {
> value=t; return
> *this: }
> template <class T> T* get() { return boost::get<T>(&value); }
> template <class T> const T* get() const { return
> boost::get<T>(&value); }
>
> private:
> boost::variant<TcpAddress> value;
> };
>
> Actuall adding an explicit copy constructor
> Shout if this doesn't work.
I had to make some adjustments, but the code below builds. I had to
remove the "explicit" from the copy constructor else TcpAddress
objects couldn't directly be assigned into a Url. Also the added
insertion for Address objects (the implementation does get() call and
then calls the TcpAddress insertion).
Please let me know what you think of this...
Thanks,
-Steve
struct Address {
public:
Address(const Address& a) : value(a.value) {}
template <class T> Address(const T& t) : value(t) {}
template <class T> Address& operator=(const T& t) { value=t;
return *this; }
template <class T> T* get() { return boost::get<T>(&value); }
template <class T> const T* get() const { return
boost::get<T>(&value); }
private:
boost::variant<TcpAddress> value;
};
std::ostream& operator<<(std::ostream& os, const Address& addr);