$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Kevlin Henney (kevlin_at_[hidden])
Date: 2004-02-26 05:07:41
In message <200402261036.28459.ghost_at_[hidden]>, Vladimir Prus 
<ghost_at_[hidden]> writes
>Kevlin Henney wrote:
>
>> >(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 don't understand the meaning of neither first "this", nor the second
>"this" :-(
The absence of an 'explicit' is not a problem, and is therefore not 
something that needs a solution. The problem you had was with a 
non-conforming compiler: it is not the job of a library to fix all the 
breakages in a compiler. Sorry for not being clearer.
>> >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.
>
>If we go further, there's no reason for explicit ctors at all?
Of course not, please don't exaggerate. If you read my email and take 
the time to study more carefully the role that conversions play in the 
language you will appreciate that 'explicit' is a powerful and useful 
tool that is intended to disable implicit conversions where they are 
harmful and meaningless. I cannot see how you would "go further" to 
reach your conclusion.
Many programmers fail to distinguish between narrowing and widening 
conversions, and arrive at unnecessarily constraining guidelines as a 
result. Conversions play a role in supporting the concept of 
substitutability, which is a significantly broader concept than the 
conventional application of LSP in OO might lead you to believe.
>I think that
>quite the contrary, unless there's very compelling reason why construction
>should be implicit, it should be explicit, since that's safer.
That may be a guideline that some C++ programmers have chosen to follow, 
but it is unnecessarily strict and not really in the spirit of the 
language, IMHO. That is their preference, and there is nothing in wrong 
in having such a preference, but it is not a preference that 
boost::any's design enforces.
Implicit conversions should only be supported where they are safe and 
have a strong semantic and transparent correspondence, so where there is 
some notional substitutability between of source type wrt the target 
type, eg int to long, derived pointer to base pointer, any value to 
boost::any. A stricter guideline does not buy you any more real safety 
and it is inconvenient for the common case, so I cannot see why it would 
be a reasonable design goal.
So, by and large, single-argument constructors should be 'explicit': for 
entity types, function object types, exception types, etc this is pretty 
much a rule; for value types it is a consideration or recommendation, 
but not a blanket rule.
>How is this going to make things safer? I my case I was passing expression of
>type boost::any to function which took boost::any. Refactoring changed the
>type, and code suddenly broke. I'm not sure the above would have helped.
You were using a broken compiler: that was the root cause of the 
problem.
>For a better mix of safely and convenience, it's possible to introduce 'reset'
>method:
>
>       boost::any bar(1);
>        bar.reset(2);
Ugh. No. That again misses the point and transparency of value-based 
programming. C++ is a language that has good support for value-based 
programming. It can support meaningful conversions and restrict 
meaningless ones, at the discretion of the programmer. If you want Ada, 
you can Google for it ;->
>> The important point is that implicit conversions from boost::any should
>> not be allowed, and they never have been.
>
>And that's another question. Conversions *from* boost::any are quite verbose.
>So why try to make boost::any initialisation concise, if further usage is
>still verbose?
Again, if you study the nature and role of conversions in more detail 
you will see that your conclusion does not follow. Not all kinds of 
conversion have the same weight and consequences, and they should be 
treated accordingly: narrowing conversions are potentially dangerous, 
and need to be marked in code; widening conversions are not, and do not.
HTH
Kevlin
-- ____________________________________________________________ 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 ____________________________________________________________