Понадобилось мне как то объявить набор шаблонных структур типа:
template< typename T1, typename T2, ... >
struct some_struct {
T1 var1;
T2 var2;
};
typedef some_struct< int, char > new_type;
Да ещё с переменным числом типов.
Сваял вот такую конструкцию. Кому надо берите пользуйтесь:
#ifndef __datastruct_h__
#define __datastruct_h__
#define _NOP()
#define _E1(x) x
#define _COMA() ,
#define _SEMICOLUMN() ;
#define _TYPENAME() typename
#define _VARGF(f,x) _E1(/_E1(**f)/_NOP()/_E1(f*)/_NOP() x f _SEMICOLUMN()/_E1(**)/)
#define _VARGF_BEGIN(f,x) _E1(/_E1(**f)/_NOP()/_E1(f*)/_NOP() x f _SEMICOLUMN()/_E1(**)/)
#define _VARGF_T(f,x) _E1(/_E1(**f)/_NOP()/_E1(f*)/_COMA() _TYPENAME() x/_E1(**)/)
#define _VARGF_BEGIN_T(f,x) _E1(/_E1(**f)/_NOP()/_E1(f*)/_NOP() _TYPENAME() x/_E1(**)/)
#define _TV_BEGIN(t,v) \
_VARGF_BEGIN(v,t)
#define _TV(t,v) \
_VARGF(v,t)
#define _VARGTI(x) _E1(/_E1(**x)/_NOP()/_E1(x*)/_COMA() x/_E1(**)/)
#define _VARGTI_BEGIN(x) _E1(/_E1(**x)/_NOP()/_E1(x*)/_NOP() x/_E1(**)/)
#define DECLARE_STRUCT_T(name, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11) \
template< _VARGF_BEGIN_T(m1,T1) _VARGF_T(m2,T2) _VARGF_T(m3,T3) _VARGF_T(m4,T4) _VARGF_T(m5,T5) \
_VARGF_T(m6,T6) _VARGF_T(m7,T7) _VARGF_T(m8,T8) _VARGF_T(m9,T9) _VARGF_T(m10,T10) _VARGF_T(m11,T11) \
> \
struct name \
{ \
_TV_BEGIN(T1,m1) \
_TV(T2,m2) \
_TV(T3,m3) \
_TV(T4,m4) \
_TV(T5,m5) \
_TV(T6,m6) \
_TV(T7,m7) \
_TV(T8,m8) \
_TV(T9,m9) \
_TV(T10,m10) \
_TV(T11,m11) \
};
#define DECLARE_TYPE_T(new_type, s_name, t1, m1, t2, m2, t3, m3, t4, m4, t5, m5, t6, m6, t7, m7, t8, m8, t9, m9, t10, m10, t11, m11 ) \
DECLARE_STRUCT_T(s_name, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11 ) \
typedef s_name< _VARGTI_BEGIN(t1) _VARGTI(t2) _VARGTI(t3) _VARGTI(t4) _VARGTI(t5) _VARGTI(t6) \
_VARGTI(t7) _VARGTI(t8) _VARGTI(t9) _VARGTI(t10) _VARGTI(t11) \
> new_type;
#endif
Для примера вот это:
typedef void* void_ptr;
DECLARE_STRUCT_T( test_struct, x, y, z )
DECLARE_TYPE_T(new_type, sstruct, int, x, const char, z, void_ptr, y )
Раскроется вот в это:
template< typename T1 , typename T2 , typename T3 >
struct test_struct {
T1 x ;
T2 y ;
T3 z ;
};
template< typename T1 , typename T2 , typename T3 >
struct sstruct {
T1 x ;
T2 z ;
T3 y ;
};
typedef sstruct< int , const char , void_ptr > new_type;
Что можно было сделать лучше?
Это преобразование аргументов t1, t2, ... макроса DECLARE_TYPE_T()
внутри кода макроса в:
typedef t1 tt1;
typedef t2 tt2;
Потому как если в качестве аргумента будет выступать тип* то макрос будет раскрыт не правильно.
Из за этого для void* в тестовом примере пришлось сделать typedef void* void_ptr;
Если будет желание сделаю. А мне и так как есть сгодилось.
Здравствуйте, nen777w, Вы писали:
N>Понадобилось мне как то объявить набор шаблонных структур типа:
вижу свою
поделкуАвтор: Vain
Дата: 08.06.06
из _E1...
N>N>template< typename T1, typename T2, ... >
N>struct some_struct {
N> T1 var1;
N> T2 var2;
N>};
N>typedef some_struct< int, char > new_type;
N>
N>Да ещё с переменным числом типов.
N>Сваял вот такую конструкцию. Кому надо берите пользуйтесь:
Во первых, можно пойти другим путём:
struct Nothing;
//Объявляем прозапас
template<typename T1, typename T2 = Nothing, typename T3 = Nothing, /*до тех пор пока руки не устанут :)*/>
struct some_struct;
//тоже, только на boost.preprocessor'е (http://www.boost.org/doc/libs/1_35_0/libs/preprocessor/doc/index.html)
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#define MYSIZE 32
#define DECL(z, n, text) T ## n = Nothing;
template< typename T1, BOOST_PP_REPEAT_FROM_TO(2, MYSIZE, DECL, typename T)>
struct some_struct;
Тоже самое с телом, думаю идею вы поняли?
Во вторых, студия 2005 понимает макросы с переменным числом аргументов, см.
__VA_ARGS__.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
О спасибо!
Пора освоить boost::preprocessir
Да
Подделка ваша.
Я её ещё
здесьАвтор: nen777w
Дата: 13.06.08
использовал. Когда писал макросы для логера.
Очень в 6-ке пригодилось.
Кстати абсолютно потокобезопасная штука, которая позволяет char* возвращать без опасений.
То что в коде стоит комент /* Unsafe for MT */ это ошибка. Исторически остался.
Про 2005 и переменное число аргументов в макросе знаю.
Вот если бы они ещё typeof ввели
Кстати как с этим в 2008 ?