Topic: cv-qualified function type--proposed resolution to 295 is bad.


Author: "Paul Mensonides" <pmenso57@attbi.com>
Date: Wed, 20 Mar 2002 17:29:58 CST
Raw View
Ignoring a cv-qualification on a function-type that is a typedef or template
parameter takes away the only way that we have of detecting an unbounded
function-type with template meta-programming constructs.

Consider:

template<class T> struct is_ref {
    enum { value = false };
};

template<class T> struct is_ref<T&> {
    enum { value = true };
};

template<class T> class is_function {
    private:
        typedef char small_t;
        struct large_t {
            char unused[256];
        };

        template<class U> static small_t check(const U*);
        template<class U> static large_t check(...);

    public:
        static const bool value = sizeof(check<T>(0)) == sizeof(large_t) &&
!is_ref<T>::value;
};

template<class T> const bool is_function<T>::value;

This implementation *relies* on the fact that template type deduction eliminates
the first 'check' because it attempts to create a cv-qualified function type.

Without something like this, you have to use massive repetition, and you no
longer have an unbounded solution.

I have no problem with the ignoring it in general cases, but the last bullet in
14.8.2 allows us to distinguish a function type.  With references, this argument
is not applicable, because there are other ways to detect that in a fully
general way.  But, short of massive, bounded partial specialization, this is the
only known way of detecting a function type.

i.e.

template<class> struct is_function {
    enum { value = false };
};

template<class R> struct is_function<R (void)> {
    enum { value = true };
};

template<class R, class T1> struct is_function<R (T1)> {
    enum { value = true };
};

template<class R, class T1, class T2> struct is_function<R (T1, T2)> {
    enum { value = true };
};

// etc.

Paul Mensonides

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "leavings" <leavings@attbi.com>
Date: Thu, 21 Mar 2002 01:40:24 GMT
Raw View
Ignoring a cv-qualification on a function-type that is a typedef or template
parameter takes away the only way that we have of detecting an unbounded
function-type with template meta-programming constructs.

Consider:

template<class T> struct is_ref {
    enum { value = false };
};

template<class T> struct is_ref<T&> {
    enum { value = true };
};

template<class T> class is_function {
    private:
        typedef char small_t;
        struct large_t {
            char unused[256];
        };

        template<class U> static small_t check(const U*);
        template<class U> static large_t check(...);

    public:
        static const bool value = sizeof(check<T>(0)) == sizeof(large_t) &&
!is_ref<T>::value;
};

template<class T> const bool is_function<T>::value;

This implementation *relies* on the fact that template type deduction eliminates
the first 'check' because it attempts to create a cv-qualified function type.

Without something like this, you have to use massive repetition, and you no
longer have an unbounded solution.

I have no problem with the ignoring it in general cases, but the last bullet in
14.8.2 allows us to distinguish a function type.  With references, this argument
is not applicable, because there are other ways to detect that in a fully
general way.  But, short of massive, bounded partial specialization, this is the
only known way of detecting a function type.

i.e.

template<class> struct is_function {
    enum { value = false };
};

template<class R> struct is_function<R (void)> {
    enum { value = true };
};

template<class R, class T1> struct is_function<R (T1)> {
    enum { value = true };
};

template<class R, class T1, class T2> struct is_function<R (T1, T2)> {
    enum { value = true };
};

// etc.

Paul Mensonides


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: pdimov@mmltd.net (Peter Dimov)
Date: Thu, 21 Mar 2002 17:23:47 GMT
Raw View
"leavings" <leavings@attbi.com> wrote in message news:<000001c1d066$0f30c2e0$7772e50c@c161550a>...
> Ignoring a cv-qualification on a function-type that is a typedef or template
> parameter takes away the only way that we have of detecting an unbounded
> function-type with template meta-programming constructs.
[...]
> I have no problem with the ignoring it in general cases, but the last bullet in
> 14.8.2 allows us to distinguish a function type.  With references, this argument
> is not applicable, because there are other ways to detect that in a fully
> general way.  But, short of massive, bounded partial specialization, this is the
> only known way of detecting a function type.

Can't you exploit the fact that a reference to a function type is
implicitly convertible to a pointer to the same type without an
user-defined conversion?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: rani_sharoni@hotmail.com (Rani Sharoni)
Date: Thu, 21 Mar 2002 18:20:12 GMT
Raw View
"leavings" <leavings@attbi.com> wrote in message news:<000001c1d066$0f30c2e0$7772e50c@c161550a>...
> Ignoring a cv-qualification on a function-type that is a typedef or template
> parameter takes away the only way that we have of detecting an unbounded
> function-type with template meta-programming constructs.
>

Hello Paul:

Don't worry because there is another way to implement the is_function
using 14.8.2/2 even after 295:

template<typename>
struct is_reference
{ static const bool result = false; };

template<typename T>
struct is_reference<T&>
{ static const bool result = true; };

template<typename, typename>
struct is_same
{ static const bool result = false; };

template<typename T>
struct is_same<T,T>
{ static const bool result = true; };


template<typename T>
struct is_function
{
private:
    typedef char (&yes)[1];
    typedef char (&no) [2];

    template<typename U> static no  check(U (*)[1]);
    template<typename  > static yes check(...);

public:
    //
    // Attempting to create an array with an element type that is
    // void, a function type, or a reference type fails the deduction
    //
    static const bool result =
        sizeof(check<T>(0)) == sizeof(yes)
        && !is_reference<T>::result
        && !is_same<T,void>::result;
    //  D.R ? && !is_class<T>::result
};


typedef int test[ is_function<void(int,char)>::result];
typedef int test[!is_function<int>::result];


Complied fine with Comeau C/C++ 4.3 BETA#2 strict mode.

There is another interesting open issue regarding abstract types and
14.8.2/2- http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#337
(Attempt to create array of abstract type should cause deduction to
fail).

This can change the is_pointer a bit     add the is_class check. More
important is that using this we could implement the is_abstrsct_class
(array type fails for this class type).


Rani

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "leavings" <leavings@attbi.com>
Date: Fri, 22 Mar 2002 15:48:15 GMT
Raw View
"Peter Dimov" <pdimov@mmltd.net> wrote in message
news:7dc3b1ea.0203210351.416f316f@posting.google.com...

[snip]

> Can't you exploit the fact that a reference to a function type is
> implicitly convertible to a pointer to the same type without an
> user-defined conversion?

I didn't know you could do this:

void f();

int main() {
    void (& rf)() = f;
    void (* pf)() = rf;
    return 0;
}

What was I thinking? :)  Well, actually I was assuming that you had to
explicitly take the address of it.  In that case, go ahead an remove it. :)

Paul Mensonides



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]