Boost logo

Boost :

Subject: Re: [boost] [optional] Changes in Boost.Optional
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2014-09-08 12:20:13


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.
>

I went to see how Boost.Variant addresses this problem. Interestingly, it
doesn't.

#include <boost/variant.hpp>

struct Wrapper
{
  operator int () { return 9; }
  operator boost::variant<int, long> () { return 7; }
};

int main()
{
  boost::variant<int, long> v = Wrapper();
  assert(boost::get<int>(v) == 7);
}

This program assertion-fails on MSVC.

Regards,
&rzej


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