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);

Reply via email to