$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [Boost-users] can't extend boost::any on windows
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2008-12-16 13:49:34
AMDG
Michael Linck wrote:
> Hi, I've implemented a simple, low level json formatting utility to 
> complement tinyjson's lightweight parser.  To do this, I've extended 
> boost::any only to add a "format()" function to it that is aware of 
> what types the content can take in a json structure and produces the 
> appropriate string.  The default constructor and the constructor with 
> a value are the only things I implemented, aside from the format 
> function.  Both just call the base constructor.  Compiled in gcc, 
> everything works fabulously.  Apparently, a functioning assignment 
> operator and copy constructor are appropriately inherited and 
> everything runs great.  On windows, however, some subtle difference 
> causes assignment and copies to seg-fault.  The real problem is that, 
> for the life of me, I can't find a way to implement assignment or 
> copies explicitly, that doesn't also bomb out.  I can probably come up 
> with a work around that stores my type in shared pointers so they're 
> never actually copied, but I'm really curious if anyone could explain 
> what causes this.  Here are some code snippets to illustrate the 
> behavior:
>
> <snip>
>
> I'm not going to list the different ways I've attempted to implement 
> copy and assignment, some more plausible than others, out of respect 
> for brevity.  If you try a build on windows, VC8, you should be able 
> to mess around with this to your hearts content.  It's really annoying 
> because it was a factor in the fundamental elegance of the parsing 
> implementation, because I see no reason why it shouldn't work, because 
> it worked fine in linux, and because it put my windows port at least a 
> day behind customer expectations.
msvc gets the copy constructor and assignment operator wrong in
the presence of a templated base class constructor/assignment operator.
You need to define them explicitly.
class Value : public boost::any {
public:
    // <snip>
    Value(const Value& arg) : boost::any(static_cast<const 
boost::any&>(arg)){}
    Value& operator=(const Value& arg) {
        static_cast<Value&>(*this) = static_cast<const boost::any&>(arg);
    }
};
In Christ,
Steven Watanabe