Boost logo

Boost :

Subject: Re: [boost] [optional] Changes in Boost.Optional
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2014-09-02 10:00:46


2014-09-02 15:57 GMT+02:00 Andrzej Krzemienski <akrzemi1_at_[hidden]>:

>
>
>
> 2014-09-02 13:39 GMT+02:00 Andrzej Krzemienski <akrzemi1_at_[hidden]>:
>
>
>>
>>
>> 2014-09-02 11:23 GMT+02:00 Dean Michael Berris <mikhailberis_at_[hidden]>:
>>
>>
>>>
>>>
>>> > I just verified that your code example works with 1.55 on VS2010, so
>>> it is
>>> > a regression. I will not be able to have a look at it for the next
>>> couple
>>> > of days. I would like to determine why it even works on 1.55. The
>>> > converting constructor from arbitrary U is also explicit in 1.55, so it
>>> > works because of some sequence of conversions that I cannot figure out
>>> > right now.
>>> >
>>> >
>>> Right. My hunch is that 1.56 now has suppression for the cases where
>>> references would have been deduced (as discussed in
>>>
>>> http://www.boost.org/doc/libs/1_56_0/libs/optional/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html
>>> ).
>>> Maybe the suppression applies even for the case when the conversion
>>> operator may have been useful for copy initialization.
>>>
>>
>> However, it works fine with GCC. It looks like VC++ compiler has a bug in
>> overload resolution in copy initialization. It should never consider
>> explicit constructors.
>>
>
> Ok, I managed to isolate the problem. The following code does not compile
> on VC++2010, although it is correct:
>
> struct A
> {
> A(int &&) {}
> A(A &&) {}
>
> template <typename T>
> explicit A(T&&) {}
> };
>
> struct B
> {
> operator A() { return A(1); }
> operator int() { return 0; }
> };
>
> int main()
> {
> A t = B();
> }
>
> The unambiguous conversion path is to use B::operator A(), but VC++
> somehow finds it ambiguous.
>

And the above incorrect behaviour is the consequence of a more simple bug
in VC++. It allows two user defined conversions in copy initialization:

struct A
{
  A(int &&) {}

};

struct B
{
  operator int() { return 0; }
};

int main()
{
  A t = B();
}

This works in VC++, although the code is incorrect.


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