Well, I have a question. If all you want is a static id per class instance, and you aren't adverse to something like this:
class derived : public base < derived > {};
You dont' need to implement _anything_ involved w/ RTTI, but you don't get a string constant. If you aren't adverse to a macro, then you can get a string.
It's creative meta-macro-programming, as MKH said. It's pretty nifty, I like it... and the ID is even at compile time. Useful. But ...probably not for you .
Anyway, if you want it, just post. I think it even works on MSVC6 (gasp).
[edited by - risingdragon3 on May 5, 2003 4:29:14 PM]
[edited by - risingdragon3 on May 5, 2003 4:29:42 PM]
Enforcing behaviour in derived classes (C++)
Hmm... but doesn''t that mean you can''t do virtual functions/polymorphism, since each derived class would inherit from a different specialization of the base class?
How appropriate. You fight like a cow.
How appropriate. You fight like a cow.
Well, I was imagining that the template would be defined like this:
...useful? I dunno. but definitely cool
EDIT: silly ;'s
EDIT2: Of course you would have to edit the recursive template to nibble at the recursion, this is not "industrial strength": depending on your compiler, you may hit the template recursive limit if you define more then say 60 types. If you nibble you can get as many as you want.
[edited by - risingdragon3 on May 5, 2003 4:41:43 PM]
[edited by - risingdragon3 on May 5, 2003 4:43:04 PM]
#include <iostream>#include <conio.h>namespace aux {template <int n> struct size_ret { char size[n+2];};size_ret<-1> series(...);template <class T,int n> struct get_and_inc;template <bool can> struct helper;template <> struct helper<true> { template <class T,int n> struct impl { enum {value = n}; friend size_ret<n+1> series(size_ret<n>*); };};template <> struct helper<false> { template <class T,int n> struct impl { enum {value = get_and_inc<T,n+1>::value}; };};template <class T,int n> struct get_and_inc { enum {current_value = sizeof(series((size_ret<n>*)0))-2}; enum {is_null = current_value == -1}; enum {value = helper<is_null>::template impl<T,n>::value};};}//assumes base_type is your "true" basestruct base_type {virtual const int get_id() = 0;};template <class child_type> class base : public base_type {enum {ID = aux::get_and_inc<child_type,0>::value};virtual const int get_id() {return ID;}};struct child_a : public base<child_a> {};struct child_b : public base<child_b> {};using namespace std;int main() {base_type* ptr = new child_a;cout << ptr->get_id();delete ptr;ptr = new child_b;cout << ptr->get_id();delete ptr;getch();}
...useful? I dunno. but definitely cool
EDIT: silly ;'s
EDIT2: Of course you would have to edit the recursive template to nibble at the recursion, this is not "industrial strength": depending on your compiler, you may hit the template recursive limit if you define more then say 60 types. If you nibble you can get as many as you want.
[edited by - risingdragon3 on May 5, 2003 4:41:43 PM]
[edited by - risingdragon3 on May 5, 2003 4:43:04 PM]
I just realized that you can also check at compile time to see how many derived classes you have declared:
Interesting. This is like compile time variables, in a way. Hmmm...could I do subtraction?..I don''t think that''s possible...wait...yes..i could...
*tests*...I''ll report back.
template <bool can> struct get_helper;template <> struct get_helper<true> { template <class T,int n> struct impl { enum {value = n}; };};template <> struct get_helper<false> { template <class T,int n> struct impl { enum {value = get_and_inc<T,n+1>::value}; };};template <class T,int n> struct get { enum {current_value = sizeof(series((size_ret<n>*)0))-2}; enum {is_null = current_value == -1}; enum {value = get_helper<is_null>::template impl<T,n>::value};};
Interesting. This is like compile time variables, in a way. Hmmm...could I do subtraction?..I don''t think that''s possible...wait...yes..i could...
*tests*...I''ll report back.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement