Boost logo

Boost :

From: Bjorn.Karlsson_at_[hidden]
Date: 2002-04-24 05:07:25


> From: John Harris (TT) [mailto:john.harris_at_[hidden]]
>
> Is the author/maintainer of boost::any out there? Is this problem not
> worthy of anyone's reply? As it is, I have to modify boost
> source to get my
> code to work. We want boost::any ctor to be "explicit"...that's it.
>

Well, I think it is worthy of a reply, so here goes ;-)

> I think the template constructor for boost::any is too
> general. I ran into
> the problem while trying to overload
>
> ostream&operator<<(ostream&, const boost::any&)
>
> If I try to do this, then all types are automatically included in this
> overload (because boost::any can be constructed from any type).
>
> I want to provide support for only a couple of types in my
> overload, and
> because of my architecture, I have to have this overload.

Even without an explicit parameterized constructor for any, there are at
least two solutions (or rather workarounds):

0) Change the declaration to ostream& operator<<(ostream&,boost::any&)
   The removal of const may be enough, but that, of course, depends on
cv-qualification of the instances (if your "real" anys are already const
that'd clearly break this hack).

1) Another level of indirection - the following should solve the problem:

struct any_print {
  any_print(const boost::any& a) : a_(a) {}
  const boost::any& a_;
};

std::ostream& operator<<(std::ostream& o, const any_print& a) {

  if (const std::string* p=boost::any_cast<std::string>(&(a.a_))) {
    std::cout << *p << '\n';
  }
  else {
    std::cout << "No match!\n";
  }

  return o;
}

Not very pretty, but it gets the job done.
 
> Is there any reason not to have boost::any::any() be explicit?
>

I think there are reasons:

0) Ease of use. With an explicit constructor, you couldn't do this:

int main() {

  std::vector<boost::any> vec;

  vec.push_back(5);
  vec.push_back(std::string(", this works!"));

  // Note that the following line uses the any_print class defined earlier
  std::cout << "Because of implicit conversion" << vec[1] << '\n';

  return 0;
}

Weak argument? Perhaps.

1) Compiler deficiencies. I gave it a quick try on three compilers, and
these were the results:
* Compiler X didn't care about explicit for templated constructors...
* Compiler Y worked!
* Compiler Z understood the explicit part, but couldn't even pass a
correctly constructed const any& to functions afterwards...

Weak argument? Perhaps.

Bjorn Karlsson



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