Boost logo

Boost :

From: Rani Sharoni (rani_sharoni_at_[hidden])
Date: 2003-03-06 10:28:26

Shame on me! I did saw before posting my answer:
[...] When the parameter has a class type and the argument expression has
the same type, the implicit conversion sequence is an identity conversion.

It seems that overloading takes place before initialization. Initialization
requires additional overloading to select the best viable constructor. In
case that the first overloading required user defined conversion then only
standard conversions are allowed in the second overloading (core issue 84).
My solution relays on the second (initialization) overloading which makes it
(and VC) wrong.

I'll be very surprise if someone will solve your challenge.

Sorry for wasting your time,

David Abrahams wrote:
> Rani,
> Here's what Steve Adamczyk (Mr. overload resolution) at EDG had to say
> about it:
> I tracked down why we do what we do. It comes down to
> 4 A conversion of an expression of class type to the same class type
> is given Exact Match rank, and a conversion of an expression of
> class type to a base class of that type is given Conversion rank,
> in spite of the fact that a copy constructor (i.e., a
> user-defined conversion function) is called for those cases.
> Now, the idea of using the auto_ptr kind of trick (copying by
> way of an auxiliary class) was not thought of when this paragraph
> was done, but the point was that for purposes of overload
> resolution copying X to X is always an exact match even if
> something is called to do the copy.
> Now, we could do a core issue to find out what this paragraph means
> for the auto_ptr kind of case. I have to say, though, that
> it would be an expensive thing to have to check everywhere that a
> copy that looks like an exact match is done, and there's nothing
> that says that calling a conversion function and copy constructor
> is less efficient than calling a copy constructor, so I'd be
> inclined to say that it should just be clarified to say that
> such a copy is considered an exact match regardless of the
> actual mechanism used to perform the copy.
> Steve
> ----- Rani wrote this ----
> Interesting challenge (at least for me).
> In first glance it seems to be impossible which made it even more
> interesting.
> typedef char (&yes)[1];
> typedef char (&no) [2];
> //
> // TODO: handle types that can't be members
> // (e.g. void, abstract, functions)
> //
> template<class T>
> struct has_regular_ctor
> {
> private:
> struct ctor_tester
> {
> T t;
> struct B {};
> operator B() const;
> ctor_tester(B);
> private:
> // VC warnings
> ctor_tester& operator=(ctor_tester const&);
> };
> static yes check(ctor_tester, int);
> template<typename U>
> static no check(ctor_tester const&, U);
> static ctor_tester const& get();
> public:
> static const bool value =
> sizeof(check(get(), 0)) == sizeof(yes);
> };
> struct A1 { A1(A1&); };
> struct A2 { A2(A2 const&); };
> typedef char test[!has_regular_ctor<A1>::value];
> typedef char test[!has_regular_ctor<A1 const>::value];
> typedef char test[ has_regular_ctor<A2>::value];
> typedef char test[ has_regular_ctor<A2 const>::value];
> typedef char test[ has_regular_ctor<int>::value];
> The above code compiled fine with VC7.1 beta but failed to compile
> using EDG and GCC.
> Here is an explanation for why I think that it's compliant:
> The form of the ctor of ctor_tester is the same as its member t
> (12.8/5). In case the ctor argument has const qualifier then both
> check functions has an exact match (, the first check
> using Lvalue-transformation and the second using identity. The
> ambiguity buster in this case is the non-template function.
> In case that the ctor is not const then the first version is viable
> using user defined conversion sequence (like auto_ptr: ctor_tester ->
> B) and the second is still identity.
> Overloading is so complex that I have doubts and I'll be happy to ear
> a second opinion.
> Rani

Boost list run by bdawes at, gregod at, cpdaniel at, john at