|
Boost : |
From: Kevlin Henney (kevlin_at_[hidden])
Date: 2004-02-25 11:08:14
In message <3D8559AE95B4D611B02C0002557C6C8BA4DB75_at_STH-EXCH>,
Bjorn.Karlsson_at_[hidden] writes
>> From: Vladimir Prus [mailto:ghost_at_[hidden]]
>> 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_at_[hidden] mobile: +44 7801 073 508 http://www.curbralan.com fax: +44 870 052 2289 Curbralan: Consultancy + Training + Development + Review ____________________________________________________________
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk