Boost logo

Boost Users :

From: Steven Watanabe (steven_at_[hidden])
Date: 2008-01-10 13:30:10


AMDG

Tobias Schwinger <tschwinger <at> isonews2.com> writes:

> > I don't think the comma operator
> > is a completely fool-proof way to detect void.
>
> It is.
>
> > It could cause an
> > ambiguity if the other type also defines an overloaded comma operator.
>
> No, because the operator is binary and one operand can have a reserved
> type which is only internally used by the test code.

Ok. Let's make this concrete. Here is what I imagine:

struct tester1 {};
struct tester2 {};

typedef char no;
struct yes { no dummy[2]; };

template<class T>
tester2 operator,(T, tester1);

template<class T>
no test(T);

template<class T>
yes test(tester2);

template<bool is_void>
struct call_impl;

template<>
struct call_impl<true> {
    template<class R, class F, class T>
    R apply(F f, T t) {
        f(t);
        BOOST_ASSERT(!"Void function cannot return to call"
                      "when the return type is not void");
    }
};

template<>
struct call_impl<false> {
    template<class R, class F, class T>
    R apply(F f, T t) {
        return(f(t));
    }
};

template<class R, class F, class T>
R call(F f, T t) {
    return call_impl<
        sizeof(test(f(t), tester1())) == sizeof(yes)
>::template apply<R>(f, t);
}

Suppose that we create a type:

struct X {};

template<class T>
T operator,(X, T);

X f(X);

And then try

call<X>(f, X())

The expression f(t), tester1() is ambiguous. It matches both
comma operators and neither operator is more specialized than
the other. How do you get around this? Remember that f(t)
only needs to be convertible to the result type so we can't
look for an exact match. Adding implicit conversions doesn't
work because the other comma operator can mirror such conversions.

In Christ,
Steven Watanabe


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net