Topic: templatizing on pointer to member


Author: "Garry Lancaster" <glancaster@ntlworld.com>
Date: Thu, 7 Mar 2002 17:45:38 GMT
Raw View
Dietmar Kuehl:
>  it is possible to create templates parameterized with a pointer to
> member:
>
>    template <typename T, typename S, T S::*mem> struct foo {};
>
> Although is nearly what I want for an application (basically to create
> manually create meta data on types), it is somewhat inconvenient to use:
>
>    struct bar { int m };
>    typedef foo<int, bar, &bar::m> fb;
>
> The problem is that the compiler already has all information by just
> specifying '&bar::m', namely that the type of the entity is
> 'int bar::*'. That is, I actually would like to a create a template
> where I can provide the parameter like this:
>
>    typedef foo<&bar::m> fb;

Hi Dietmar,

I have no solution for you I'm afraid, but I think
what you are asking for is interesting.

Currently template parameters can be either

1. A type (including a template) OR

2. A value.

In general it would be nice if there was a third
option:

3. A type and a value.

Perhaps declared with syntax like:

template <typename MyType MyValue>
....

Moving away from the general, back to your
specific requirement, were this core extension
to be present the only remaining hurdle would
be to "crack" MyType to get the object type and
member type as two separate types. That's not
easy, but it's possible with already known
metaprogramming techniques. Depending on
exactly what you want to do inside your foo
template, it may not be necessary.

Kind regards

Garry Lancaster
Codemill Ltd
Visit our web site at http://www.codemill.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.research.att.com/~austern/csc/faq.html                ]





Author: Dietmar Kuehl <dietmar_kuehl@yahoo.com>
Date: Mon, 25 Feb 2002 03:02:33 GMT
Raw View
Hi,

it is possible to create templates parameterized with a pointer to
member:

   template <typename T, typename S, T S::*mem> struct foo {};

Although is nearly what I want for an application (basically to create
manually create meta data on types), it is somewhat inconvenient to use:

   struct bar { int m };
   typedef foo<int, bar, &bar::m> fb;

The problem is that the compiler already has all information by just
specifying '&bar::m', namely that the type of the entity is
'int bar::*'. That is, I actually would like to a create a template
where I can provide the parameter like this:

   typedef foo<&bar::m> fb;

Of course, this is possible but only if I restrict instantiations to
'int' members of the type 'bar':

   template <int bar::*mem> struct foo {};

When trying to be more general, it is impossible to provide necessary
specifications that something is supposed to be a type without also
adding new template parameter. A possible approach would be the
possibility of writing something like this for the primary template and
not just for specializations:

   template <typename T, typename S, typename T S::*mem>
   struct foo<T S::*mem> { /*...*/ };
   typedef foo<&bar::m> fbm;

This would mean that the template 'foo' takes one template parameter,
ie. it can be used like 'foo<&bar::m>', but actually specifies three
template names. Using this approach other things could be determined,
too, for example:

   template <template <typename> class Cont, typename T>
   struct foobar<Cont<T> > { /*...*/ };

   typedef foobar<std::vector<int> > type;

What do people think about this? I think it would be pretty useful eg.
create compile-time lists of members... Is there possibly even something
already available which would enable something like this?
--
<mailto:dietmar_kuehl@yahoo.com> <http://www.dietmar-kuehl.de/>
Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.com/>

---
[ 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: "James Kuyper Jr." <kuyper@wizard.net>
Date: Tue, 26 Feb 2002 17:55:28 GMT
Raw View
Dietmar Kuehl wrote:
>
> Hi,
>
> it is possible to create templates parameterized with a pointer to
> member:

Yes, that's one of the four options listed in section 14.1p4.

---
[ 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: Olaf Krzikalla <Entwicklung@reico.de>
Date: Tue, 26 Feb 2002 18:09:24 GMT
Raw View
Hi,

I've experimented with this kind of things, too. You may find some of
the early results on the german newsgroup (it was about a half year
ago). I ran in exactly the same problem. Eventually I used typeof (gcc)
and a lot of makros:

template <typename T, typename S, T S::*mem> struct descriptor { /*...*/
};

template <typename T, typename S>
T getFieldType (T S::* );

#define DESC(STRUCT, FIELD) \
  descriptor<typeof (getFieldType (&STRUCT::FIELD)), STRUCT,
&STRUCT::FIELD>

I used descriptor to build a member typelist for each class. But I found
it inconvient to write the class name again and again. So I came up with
more makros:

#define DESC_2(S_NAME, F_N1, F_N2) \
  DESC (S_NAME, F_N1), DESC (S_NAME, F_N2)

etc. Then you can write:

struct Bsp1 {
  int a;
  std::string b;
  typedef TYPE<DESC_2 (Bsp1, a, b)>::LIST desc_;
};

(TYPE<>::LIST is my own non-macro way to create a Loki typelist)
In another approach I tried to deduce the struct type similiar to the
field type. But at least with gcc 2.95 it turns out, that then the
typelist definition could not be inside the class definition.

Dietmar Kuehl wrote:
> What do people think about this? I think it would be pretty useful eg.
> create compile-time lists of members...
Indeed this could be very useful. And your approach looks more
consistent to the language then the idea I had: erase the border between
types and values at a certain point:

template <typename T, typename S, T S::*mem>
inline descriptor<T, S, mem> desc (T S::* mem)
{
  return descriptor<T, S, mem>();
}

Here mem appears again as a function argument. Hence you can write:

struct Bsp1 {
  int a;
  std::string b;
  typedef TYPE<typeof (desc (&Bsp1::a)), typeof (desc (&Bsp1::b))>::LIST
desc_;
};

Of course desc() can only be called with mem known at compile time.
Otherwise it's an error. The function body may be unnecessary.
I came up with this idea some times ago when I needed integer template
parameters deduced from function-style calls. Interestingly enough, it
leads to a solution for your problem, too.


Best regards,
Olaf Krzikalla

---
[ 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                ]