Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2003-01-12 09:56:20


"Paul Mensonides" <pmenso57_at_[hidden]> writes:

> ----- Original Message -----
> From: "David Abrahams" <dave_at_[hidden]>
>
>> >> Here's an interesting turn-of-the-tables: I was experimenting with
>> >> using SFINAE to disable conversion operators, and I discovered that
>> >> almost every compiler except vc6/7 rejects this code:
>> >>
>> >> template <class T> struct voidify { typedef void type; };
>> >> template <class T> struct Y {};
>> >> struct X
>> >> {
>> >> template <class T>
>> >> operator Y<T> (typename voidify<T>::type) const { return Y<T>(); }
>> >> };
>> >
>> > Is this even legal? I.e. for a user-defined conversion operator to have
> any
>> > arguments at all?
>>
>> Look twice; the argument is void.
>
> I know, but I don't think you can derive a 'void' parameter list that way.
> E.g.
>
> template<class> struct test; // not defined
>
> template<class T> struct test<void (*)(T)> { }; // defined
>
> void f(void) { }
>
> int main() {
> test< &f >(); // error
> return 0;
> }
>
> In other words, the "void" parameter list is fundamentally different than
> "type void".

That's not a very good test case, though. *Matching* a void parameter
could easily be different from generating one. What about:

    template <class T> struct id { typedef T type; };
    struct X
    {
       void f(id<void>::type);
    };

    "ComeauTest.c", line 4: warning: declaring a void parameter list with a typedef is
              nonstandard
         operator int(id<void>::type);

??

I'd prefer it if matching void in a parameter list *were* different
from generating one. The above prevents the use of SFINAE to generate
restricted templated conversion operators.

-- 
                       David Abrahams
   dave_at_[hidden] * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution

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