
In message <3D8559AE95B4D611B02C0002557C6C8BA4DB75@STH-EXCH>, Bjorn.Karlsson@readsoft.com writes
From: Vladimir Prus [mailto:ghost@cs.msu.su] I just had a couple of bugs caused by the fact that constructor of boost::any is not explicit. For example:
void do_something(boost::any& v) { ... }
class variable { ///// boost::any& value() {} };
variable v; do_something(v);
The intention was to call do_somethin on 'v.value()' but non-explicit ctor is happy to accept 'variable', after which 'do_something' breaks.
Anybody has an opinion? Is non-explicit ctor really necessary?
(Note that the example above avoids the issue of implicit conversion (it won't compile), because it takes the parameter by non-const reference. With the current implementation, this is a good trick to use.)
The main point to take away from this is that this is not a problem ;->
I agree that the constructor should be made explicit. I seem to recall that we discussed this on the list about a year ago, and the main objection against an explicit constructor was that the behavior across different compilers wasn't consistent (some compilers didn't like explicit template constructors at all). But now, a year later, perhaps it's time to go ahead and make the change? It's unfortunate that it's a change that will break code; perhaps some legacy mode needs to be provided.
Anyway, there have been several requests for this and thus far no strong opinions against it.
I have yet to see a convincing reason to make it explicit. Autoboxing has been a part of boost::any's design from day 1, which existed before Boost -- and, indeed, the "autoboxing" terminology. Supporting such conversions was intentional. There is no more reason to make the converting constructor of boost::any explicit than there is to make the converting constructor of std::string explicit, or the conversion from int to long explicit, or the conversion from T * to void *, or indeed any other widening conversion. Of course, there is nothing to stop programmers adopting an explicit style, ie boost::any bar(1); bar = boost::any(2); void foo(const any &); foo(boost::any(3)); But there is no reason to prevent them from using the widening conversion style, ie boost::any bar = 1; bar = 2; void foo(const any &); foo(3); The choice is a matter of personal preference, but there is more convenience available in having the implicit conversion than there is safety to be achieved by making it explicit. The important point is that implicit conversions from boost::any should not be allowed, and they never have been. Kevlin PS And thanks for copying me on this, Bjorn. -- ____________________________________________________________ Kevlin Henney phone: +44 117 942 2990 mailto:kevlin@curbralan.com mobile: +44 7801 073 508 http://www.curbralan.com fax: +44 870 052 2289 Curbralan: Consultancy + Training + Development + Review ____________________________________________________________