Boost logo

Boost :

From: Rani Sharoni (rani_sharoni_at_[hidden])
Date: 2003-02-21 18:21:27


David Abrahams wrote:
> David Abrahams <dave_at_[hidden]> writes:
>
>> I'm in love with the new is_convertible; I can now detect "move-copy"
>> types like auto_ptr! Could the old is_convertible do this?
The new is_convertible can't help you:
struct A { A(); A(A&); };
void f(A);
const A a
f(a); // viable function with exact match
        // construction fail later

> OK, I give up. This doesn't work for GCC. Does anybody have a clever
> route to detecting types whose copy ctor have a non-const RHS? It's
> fine to assume that an accessible copy ctor exists.

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 (13.3.3.1.1/3), 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 acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk