   template meta-programming
  Hi, I'm working on a small template meta-programming library,  for learning and probably for later real world use. currently I'm working with type lists and I thing I found a interesting ay of coding metaprograms, but I didn't find anyone else using this, so I'm wondering if there is any gotchas in my idea:example:   template<typename H, typename T> struct List {  typedef H Type;  typedef T Next;};// at<L,N>::Type returns the Nth type in the list L//usual code:template<typename L, unsigned int N> struct at {  typedef at<typename L::Next, N-1>::Type Type;};template<typename L> struct at<L, 0> {  typedef typename L::Type Type;}//my code:template<typename L, unsigned int N> struct at :   at<typename L::Next, N-1> {};template<typename L> struct at<L, 0> : L {};my code seens to me cleaner and more "haskell like" doing the same thing usual code does but inheritance can sometimes be a invisible source of problems in meta-programming.Any recomendations?Sergio[edited by - svpace on January 30, 2004 12:12:52 PM]
  Just reposting your code in [source] tags so that I can see the stuff that dissapeared because it was interpreted as HTML tags:example template<typename H, typename T> struct List {  typedef H Type;  typedef T Next;};// at<L,N>::Type returns the Nth type in the list L//usual code:template<typename L, unsigned int N> struct at {  typedef at<typename L::Next, N-1>::Type Type;};template<typename L> struct at<L, 0> {  typedef typename L::Type Type;}//my code:template<typename L, unsigned int N> struct at :   at<typename L::Next, N-1> {};template<typename L> struct at<L, 0> : L {};EnigmaEDIT: typo   [edited by - Enigma on January 30, 2004 11:57:37 AM];  How do you plan on using your at structure? It''s not much use for creating function signatures, or specializing templated classes. For example: what if you wanted to create a std::vector using the type of the third item in your typelist? ;  it can be something like this: typedef List<int, List<char, List<float, Nil> > > types;std::vector< at<types,2>::Type> vector_of_type_2; // 0 based index [edited by - svpace on January 30, 2004 10:23:44 PM];  Except you can''t do that. You don''t have a Type typedef in your at struct. ;  in the usual code there is an explicit typedef for Type, in fact it's the only thing inside "at". in my code the Type typedef is inherited from List, and this is the difference between both codes, in my code I avoid redundant typedef's by inheriting then from some base case (partial specialization), and only the base case use an explicit typedef. the L template parameter must always be of List type, or something that implement the same typedef's otherwise there will be an compiler error   [edited by - svpace on January 30, 2004 11:40:46 PM];  Have you looked at the Loki library? Alecsandru talks about some uses of type lists in his Modern C++ Design book. Might want to see what sort of things the Loki documentation says. ;  Your code is very interesting... I have never thought of it... But really, I cant see any case in where it might be usefull. Can you give an example? I am really interested...Thank you. ;  The only possible problem i can see would be that you end up inheriting from Nil.  If Nil has a Type typedef in it, it may compile even though you wouldnt really want it to.  So you have to be careful as to the interface of the Nil type (the same applies to the non-inheritence method too, though). Apart from that, I think both methods are valid depending on how you would want to use the at template.  If you require access to the ''Next typedef'' as well as the ''Type typedef'' through the at template, then i would say using inheritance is the way to go.  If, however, you will only be using the Type typedef, then i would argue that the method not using inheritence is clearer to the reader, as it provides the at template with its own solid interface, rather than relying on the List interface. ;  Sorry for the delay but you know that damm real life, always getting in the way.antareus: got the Loki library, real great stuff, but they use the "usual code" too. danielf: real example? well as I said I''m just begining to  learn this stuff so be patient. type lists can be good for adding some reflexitivity in classes, or in some place where you need to tranform an index in some type, database maybe... it''s vague and I agree with you, actually I never used type lists... yet. But I already used some very interesting loop unroling metaprogramming to optimize a vector library I was working with. For now I''m just learning and waiting to see what comes up. If anyone have some intersting examples I will apreciate.Jing: about the Nil inheritance my code was not very complete by the time of my first post  there are some specializations of "at" to handle the Nil case. as for the readability I was so happy that my code was easier to read than usual code.... well I guess coding style is very personal stuff indeed, but thanks for the input anyway.Everybody: after some more exploratory programming I came up with some discoveries. the "my code" style seens to have some disvantages, it can''t be use for final types, types that will be actually be used for normal programming, for example consider the meta-if: //usual codetemplate<bool B, typename T, typename F> struct If {  typedef T Type;};template<typename T, typename F> struct If<false, T, F> {  typedef F, Type;}If<true, A, B>::Type a("class A");//my code template<bool B, typename T, typename F> struct If : T {};template<typename T, typename F> struct If<false, T, F> : F{};If<true, A, B> a("class A");the "my code" style would provide a subtype of A witch don''t have a string constructor unless someone know how to inherit constructors, candidates?also it creates some typesafe issues, some metafunctions (structs) use direct reference to List to avoid the Nil case template<typename L> struct foo {};template<typename H, typename T> foo< List<H, T> > { /*stuff*/ }template<typename H> foo< List<H, Nil> > { /*more stuff*/ }in these cases as "at"(or any other of the list metafunction) actually became an List instead of providing a List type foo will not recognize it and will pass it to the general case (first one) as templates don''t support polimorfism. it is possible to generalize the description to some templatized template parameter: template<template<typename H, typename T> class L> struct foo{};but we open space for errors as any two parameter template could be used. Any recomendations? typesafety or flexibility?Well that''s it for now, keep talking(typing) I''m all ears(eyes)Sérgio