Topic: is_pointer<T> gives wrong answer for pointers to member variables and member functions
Author: notbob@tessellation.com (Robert Allan Schwartz)
Date: Fri, 9 May 2003 00:27:23 +0000 (UTC) Raw View
> It should all be zero. Both types you're
> passing are pointers-to-members; which are
> not pointers (see 3.9.2/1).
>
> Daveed
What about is_pointer<int (*)(int)>? Is a
pointer-to-non-member-function considered to be a pointer?
Thanks,
Robert
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: ron@sensor.com ("Ron Natalie")
Date: Fri, 9 May 2003 00:51:05 +0000 (UTC) Raw View
"Robert Allan Schwartz" <notbob@tessellation.com> wrote in message news:1166fd92.0305081623.5e05e9a5@posting.google.com...
> > It should all be zero. Both types you're
> > passing are pointers-to-members; which are
> > not pointers (see 3.9.2/1).
> >
> > Daveed
>
> What about is_pointer<int (*)(int)>? Is a
> pointer-to-non-member-function considered to be a pointer?
>
I would say so. While it's size and encoding may be different than
a data pointer, it still behaves like a regular pointer. You can apply *
to it and get the pointed to type, and most importantly for the example
given, the declaration works right....
typedef int function(int);
typedef function* function_ptr;
is consistant.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: google@vandevoorde.com (Daveed Vandevoorde)
Date: Fri, 9 May 2003 17:20:46 +0000 (UTC) Raw View
ron@sensor.com ("Ron Natalie") wrote:
> "Robert Allan Schwartz" <notbob@tessellation.com> wrote:
[...]
> > What about is_pointer<int (*)(int)>? Is a
> > pointer-to-non-member-function considered to be a pointer?
> >
> I would say so. While it's size and encoding may be different than
> a data pointer, it still behaves like a regular pointer. You can apply *
> to it and get the pointed to type, and most importantly for the example
> given, the declaration works right....
>
> typedef int function(int);
> typedef function* function_ptr;
>
> is consistant.
That's exactly right.
Daveed
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: conley.141@osu.edu (Mike Conley)
Date: Fri, 9 May 2003 17:21:47 +0000 (UTC) Raw View
notbob@tessellation.com (Robert Allan Schwartz) wrote in
news:1166fd92.0305081623.5e05e9a5@posting.google.com:
> What about is_pointer<int (*)(int)>? Is a
> pointer-to-non-member-function considered to be a pointer?
No. Function pointers, pointers to member, member function pointers
and pointers to ordinary objects are 4 distinct classes of pointers. So
the question really is, "what kind of pointers should is_pointer test
for?"
The partial specialization for is_pointer you gave,
template <class T>
struct is_pointer<T*> //...
will match pointers to ordinary objects only. If you want is_pointer to
be true for pointers to member, you need another partial specialization,
template <class T, class C>
struct is_pointer<T C::*> //...
Note, however, that these will not match cv-qualified pointers, eg:
is_pointer<int* const> --> false
is_pointer<int some_class::* const> --> false
For that, you need some more trickery. You can either write partial
specializations for the types AND cv-qualified types, or you can do it
like this:
namespace impl { // "private" is_pointer implemenation details
template <class T> struct is_pointer //false
template <class T> struct is_pointer<T*> // true
template <class T, class C> struct is_pointer<T C::*> // true
}
template <class T>
struct is_pointer :
public impl::is_pointer<typename remove_cv<T>::type> {};
Now, if you want is_pointer to return true for pointers to function and
pointers to member function, you're going to be disappointed: it's not
possible to do generally. You can make it work for arbitrarily many
cases, though:
namespace impl {
// nullary function
template <class T>
struct is_pointer<(*T)()>
// unary function
template <class T, class A1>
struct is_pointer<(*T)(A1)>
// variadic function taking one required argument
template <class T, class A1>
struct is_pointer<(*T)(A1,...)>
// unary member function
template <class T, class C, class A1>
struct is_pointer<T (C::*)(A1)>
//...
}
Do enough of this (say up to 10 arguments), and you'll have enough to say
with reasonable confidence that your template does what you expect for the
most common cases. Just be sure to stop before you cause yourself
permanent brain damage :)
Hopefully, variadic templates will eventually be added to C++, so that one
can define a general template taking an arbitrary function type (among
other things).
--
Mike Conley
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Fri, 9 May 2003 18:09:57 +0000 (UTC) Raw View
conley.141@osu.edu (Mike Conley) writes:
| notbob@tessellation.com (Robert Allan Schwartz) wrote in
| news:1166fd92.0305081623.5e05e9a5@posting.google.com:
|
| > What about is_pointer<int (*)(int)>? Is a
| > pointer-to-non-member-function considered to be a pointer?
|
| No. Function pointers, pointers to member, member function pointers
| and pointers to ordinary objects are 4 distinct classes of pointers. So
| the question really is, "what kind of pointers should is_pointer test
| for?"
|
| The partial specialization for is_pointer you gave,
|
| template <class T>
| struct is_pointer<T*> //...
|
| will match pointers to ordinary objects only.
It will match a pointer to function also. 8.3.1/1
In a declaration T D where D has the form * cv-qualifier-seq opt D1
and the type of the identifier in the declaration T D1 is
derived-declarator-type-list T, then the type of the identifier of
D is derived-declarator-type-list cv-qualifier-seq pointer to T.
The cv-qualifiers apply to the pointer and not to the object pointed
to.
Anytime T is type, T* is pointer, or said in less academic verbiage,
a type is a pointer each time it can be written as "T*", where T is a
type-id.
--
Gabriel Dos Reis, gdr@integrable-solutions.net
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: conley.141@osu.edu (Mike Conley)
Date: Fri, 9 May 2003 20:15:48 +0000 (UTC) Raw View
gdr@integrable-solutions.net (Gabriel Dos Reis) wrote in
news:m31xz8c8ep.fsf@uniton.integrable-solutions.net:
> It will match a pointer to function also. 8.3.1/1
Dah! It appears I managed to confound the rules for pointer conversion
with template matching for pointers (How did I do this? No idea). Thanks
for the correction.
--
Mike Conley
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: notbob@tessellation.com (Robert Allan Schwartz)
Date: Thu, 8 May 2003 03:16:15 +0000 (UTC) Raw View
The program:
template <typename T>
class is_pointer { public: static const bool value = false; };
template <typename T>
class is_pointer<T *> { public: static const bool value = true; };
#include <iostream>
class i_am_a_class { };
int main()
{
std::cout << "is_pointer<int i_am_a_class::* >::value = " <<
is_pointer<int i_am_a_class::* >::value << std::endl;
std::cout << "is_pointer<int (i_am_a_class::*)(void)>::value = " <<
is_pointer<int (i_am_a_class::*)(void)>::value << std::endl;
return 0;
}
gives the results:
is_pointer<int i_am_a_class::* >::value = 1
is_pointer<int (i_am_a_class::*)(void)>::value = 0
on g++ v3.2, but gives the results:
is_pointer<int i_am_a_class::* >::value = 0
is_pointer<int (i_am_a_class::*)(void)>::value = 0
on metrowerks v7.
I believe the answers should all be 1.
What does the standard say?
Thank you,
Robert Schwartz
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]