IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

template dans template - c'est possible ?


Sujet :

Langage C++

  1. #1
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut template dans template - c'est possible ?
    Bonsoir, j'essaye de définir (prédéclarer pour être plus précis) un template à l'intérieur d'un autre template.

    Cf, ce bout de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    namespace kazu
    {
    	template<typename scalarT>
    	struct	blast
    	{
    		//vec fwd decl
    		class	vec2;
    		class	vec3;
    		class	vec4;
     
     
    		//typedefs
    		typedef	scalarT	scalar;
     
    		//utility classes
    		template<class vecT, unsigned int sizeT>
    		class	vecproto;
     
    }//namespace kazu
    Puis, je définis/précise le template de cette facon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    template<typename typeT, class selfT, unsigned int dimT>
    struct	kazu::blast<typeT>::vecproto<selfT, dimT> :
    	public boost::arithmetic< selfT, 
    		boost::multiplicative< selfT, typeT,
    		kazu::unary<selfT, typeT, dimT,
    		kazu::binary<selfT, typeT, dimT,
    		kazu::trinary<selfT, typeT, dimT
    	> > > > >
    {
    //	selfT(typeT a[dimT])	{	for (unsigned i = 0; i < dimT; i++){ this->_a[i] = a[i]; }	}
     
    	//sum
    	inline	typeT	sum()	{	typeT rv = (typeT)0;	for(unsigned int i = 0; i < dimT; i++){rv += this->_a[i];}	return rv;	}
     
    	//dot
    	virtual	typeT	dot(const selfT& b)	{	selfT rv(*this); rv *= b; return rv.sum(); 	}
    	inline	friend	typeT	dot(const selfT& a, const selfT& b)	{	return a.dot(b);	}
     
    	//cross
    //	virtual	selfT	cross(const selfT& b);	//todo: implement in specialization
    	inline	friend	selfT	cross(const selfT& a, const selfT& b)	{	return a.cross(b);	}
     
    	//length
    	inline	typeT	lensq()	{	selfT a(*this); a *= a; return a.sum();		}
    	inline	friend	typeT	lensq(const selfT& a)	{	return	a.lensq();	}
     
    	inline	typeT	length()	{	return std::sqrt<typeT>( lensq() );		}
    	inline	friend	typeT	length(const selfT& a)	{	return a.length();	}
     
    	inline	typeT	distance(const selfT& rhv)	{	selfT a = rhv - (*this); return a.length();	}
    	inline	friend	typeT distance(const selfT& a, const selfT& b)	{	return a.distance(b);	}
     
    	//operators
    	virtual	selfT&	operator=(const selfT& b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] = b._a[i];	}	}
    	virtual	selfT&	operator+=(const selfT& b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] += b._a[i];	}	}
    	virtual	selfT&	operator-=(const selfT& b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] -= b._a[i];	}	}
    	virtual	selfT&	operator*=(const selfT& b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] *= b._a[i];	}	}
    	virtual	selfT&	operator/=(const selfT& b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] /= b._a[i];	}	}
     
    	virtual	selfT&	operator*=(const typeT b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] *= b;	}	}
    	virtual	selfT&	operator/=(const typeT b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] /= b;	}	}
     
    	//this ought to crash the compiler, or at least induce errors
    //	selfT&	operator+=(const selfT& b)	{	(*this) = (*this) + b;	}
    //	selfT&	operator-=(const selfT& b)	{	(*this) = (*this) - b;	}
    //	selfT&	operator*=(const selfT& b)	{	(*this) = (*this) * b;	}
    //	selfT&	operator/=(const selfT& b)	{	(*this) = (*this) / b;	}
     
    	inline	typeT&		operator[](unsigned int idx)	{	assert(idx < dimT); return this->_a[idx];	}
    	inline	operator	typeT*()						{	return &this->_a[0];	}
     
    	//swizzle
    	template<unsigned int X>	inline	typeT&			get()		{	BOOST_STATIC_ASSERT(X < dimT); return this->_a[X];	}
    	template<unsigned int X>	inline	const typeT&	get() const	{	BOOST_STATIC_ASSERT(X < dimT); return this->_a[X];	}
     
    	template<unsigned int X, unsigned int Y>
    	vec2 swizzle2();
    	template<unsigned int X, unsigned int Y>
    	const vec2 swizzle2() const ;
     
    	template<unsigned int X, unsigned int Y, unsigned int Z>
    	vec3 swizzle3();
    	template<unsigned int X, unsigned int Y, unsigned int Z>
    	const vec3 swizzle3() const;
     
    	template<unsigned int X, unsigned int Y, unsigned int Z, unsigned int W>
    	vec4 swizzle4();
    	template<unsigned int X, unsigned int Y, unsigned int Z, unsigned int W>
    	const vec4 swizzle4() const;
     
    	std::ostream& operator<<(std::ostream& os)
    	{
    		os << "vec" << dimT << " [";
    		for(unsigned int i = 0; i < dimT; i++)
    		{	
    			if(i)
    				os << ", ";
    			os << (*this)[i];			
    		}
    		os << "]";
    		return os;
    	}
    };
    et enfin, je me sers du template^2 de cette facon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    template<typename typeT>
    struct kazu::blast<typeT>::vec2 : public kazu::blast<typeT>::vecproto<vec2, 2>
    {
    	union
    	{
    		typeT	_a[2];
    		struct { typeT x, y; };
    		struct { typeT i, a; };
    		struct { typeT s, t; };
    		struct { typeT _0, _1; };		
    	};
     
    	vec2()	{}	
    	vec2(const vec2& b): x(b.x), y(b.y)	{}
    	vec2(typeT _x, typeT _y): x(_x), y(_y)	{}	
    	virtual ~vec2(){}
     
    	//todo: declare swizzle functions here
    	vec2	xx();
    	vec3	xxx();
    	vec4	xxxx();
     
    	const	vec2	xx()	const;
    	const	vec3	xxx()	const;
    	const	vec4	xxxx()	const;
    };
     
    template<typename typeT>
    struct kazu::blast<typeT>::vec3 : public kazu::blast<typeT>::vecproto<vec3, 3>
    {
    	union
    	{
    		typeT	_a[3];
    		struct { typeT x, y, z; };
    		struct { typeT r, g, b; };
    		struct { typeT s, t, p; };
    		struct { typeT _0, _1, _2; };		
    	};
     
    	vec3()	{}	
    	vec3(const vec3& b): x(b.x), y(b.y), z(b.z)	{}
    	vec3(typeT _x, typeT _y, typeT _z): x(_x), y(_y), z(_z)	{}	
    	vec3(const vec2& b): x(b.x), y(b.y), z((typeT)0)	{}
    	virtual ~vec3(){}
     
    	//todo: declare swizzle functions here
    	vec2	xx();
    	vec3	xxx();
    	vec4	xxxx();
     
    	const	vec2	xx()	const;
    	const	vec3	xxx()	const;
    	const	vec4	xxxx()	const;
    };
     
    template<typename typeT>
    struct kazu::blast<typeT>::vec4 : public kazu::blast<typeT>::vecproto<vec4, 4>
    {
    	union
    	{
    		typeT	_a[4];
    		struct { typeT x, y, z, w; };
    		struct { typeT r, g, b, a; };
    		struct { typeT s, t, p, q; };
    		struct { typeT _0, _1, _2, _3; };		
    	};
     
    	vec4()	{}	
    	vec4(const vec4& b): x(b.x), y(b.y), z(b.z), w(b.w)	{}
    	vec4(typeT _x, typeT _y, typeT _z, typeT _w): x(_x), y(_y), z(_z), w(_w)	{}	
    	vec4(const vec2& b): x(b.x), y(b.y), z((typeT)0), w((typeT)1)	{}
    	vec4(const vec3& b): x(b.x), y(b.y), z(b.z), w((typeT)1)		{}
    	virtual ~vec4(){}
     
    	//todo: declare swizzle functions here
    	vec2	xx();
    	vec3	xxx();
    	vec4	xxxx();
     
    	const	vec2	xx()	const;
    	const	vec3	xxx()	const;
    	const	vec4	xxxx()	const;
    };
    la première erreur que le compilo me lance est celle-ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     error C2992: "kazu::blast<scalarT>::vecproto<selfT,dimT>": Faultive or missing template parameter list.
    Je suppose que le truc du template sous template ne fonctionne pas...
    C'est bien ca, ou il y a un autre truc qui cloche?

  2. #2
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    heu, il me semble que c'est la syntaxe qui est fautive: remplace
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template<typename typeT, class selfT, unsigned int dimT>
    struct	kazu::blast<typeT>::vecproto<selfT, dimT> :
    Par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template<typename typeT> template<class selfT, unsigned int dimT>
    struct	kazu::blast<typeT>::vecproto<selfT, dimT> :

    Bonne chance
    Méphistophélès
    Si la solution ne résout pas votre problème, changez le problème...
    Cours et tutoriels C++ - FAQ C++ - Forum C++.

  3. #3
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    Merci, c'était bien ca la première erreur (il en reste 3), et ej viens d'apprendre une nouvelle chose: on peut mettre plus d'un template dans une définition.

    voici le code source actuel dans son entièreté (ca deviendra LGPL/OpenSource, donc aucune raison de le cacher):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    //!     \file   Kazu.cpp
    //!     @brief  fast test for kazu
     
     
    //---------------------------------------------------------------------------
    //Boost.asserts
    #include <boost/static_assert.hpp>
     
    //Boost.operators
    #include <boost/operators.hpp>
     
    //SL.Math
    #include <cmath>
     
    //SL.assert
    #include <cassert>
     
    //STL.cout
    #include <iostream>
    //////////////////////////////////////////////////////////////////////////
    //forward declaration 
     
    namespace kazu
    {
    	template<typename scalarT>
    	struct	blast
    	{
    		//vec fwd decl
    		class	vec2;
    		class	vec3;
    		class	vec4;
    		class	vec4D;
     
    		//mat fwd decl
    		class	mat2x2;
    		class	mat2x3;
    		class	mat2x4;
     
    		class	mat3x2;
    		class	mat3x3;
    		class	mat3x4;
     
    		class	mat4x2;
    		class	mat4x3;
    		class	mat4x4;
     
    		//other fwd decl: complex, hypercomplex
    		class	complex;
    		class	quaternion;
    		class	octonion;
     
    		//typedefs
    		typedef	scalarT	scalar;
    		typedef	mat2x2	mat2;
    		typedef	mat3x3	mat3;
    		typedef	mat4x4	mat4;
     
    		//utility classes
    		template<class vecT, unsigned int sizeT>
    		class	vecproto;
     
    		template<class matT, class transT, unsigned int sizeA, unsigned int sizeB>
    		class	matproto;
    	};
    }//namespace kazu
     
    //////////////////////////////////////////////////////////////////////////
    //vecproto - template definition
     
    namespace kazu
    {
    	template<class selfT, typename typeT, unsigned int dimT, class B = ::boost::detail::empty_base<selfT> >
    	struct	unary : B
    	{
    		friend	selfT	sin(const selfT& a)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)sin( a._a[i] );	}	return rv;	}
    		friend	selfT	cos(const selfT& a)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)cps( a._a[i] );	}	return rv;	}
    		friend	selfT	tan(const selfT& a)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)tan( a._a[i] );	}	return rv;	}
    		friend	selfT	asin(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)asin( a._a[i] );	}	return rv;	}
    		friend	selfT	acos(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)acos( a._a[i] );	}	return rv;	}
    		friend	selfT	atan(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)atan( a._a[i] );	}	return rv;	}
    		friend	selfT	exp(const selfT& a)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)exp( a._a[i] );	}	return rv;	}
    		friend	selfT	log(const selfT& a)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)log( a._a[i] );	}	return rv;	}
    		friend	selfT	exp2(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)exp2( a._a[i] );	}	return rv;	}
    		friend	selfT	log2(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)log2( a._a[i] );	}	return rv;	}
    		friend	selfT	sqrt(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)sqrt( a._a[i] );	}	return rv;	}
    		friend	selfT	abs(const selfT& a)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)abs( a._a[i] );	}	return rv;	}
    		friend	selfT	sign(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)sign( a._a[i] );	}	return rv;	}
    		friend	selfT	floor(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)floor( a._a[i] );	}	return rv;	}
    		friend	selfT	ceil(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)ceil( a._a[i] );	}	return rv;	}		
    	};
     
    	template<class selfT, typename typeT, unsigned int dimT, class B = ::boost::detail::empty_base<selfT> >
    	struct	binary : B
    	{
    		friend	selfT	pow(const selfT& a, const selfT& b)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)pow( a._a[i], b._a[i] );	}	return rv;	}
    		friend	selfT	pow(const selfT& a, const typeT b)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)pow( a._a[i], b );	}	return rv;	}
     
    		friend	selfT	min(const selfT& a, const selfT& b)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)min( a._a[i], b._a[i] );	}	return rv;	}
    		friend	selfT	max(const selfT& a, const selfT& b)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)max( a._a[i], b._a[i] );	}	return rv;	}
    	};
     
    	template<class selfT, typename typeT, unsigned int dimT, class B = ::boost::detail::empty_base<selfT> >
    	struct	trinary : B
    	{
    		friend	selfT	clamp(const selfT& a, const selfT& b, const selfT& c)		
    		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)clamp( a._a[i], b._a[i], c._a[i] );	}	return rv;	}
    	};
    }
     
     
     
    //////////////////////////////////////////////////////////////////////////
     
    template<typename typeT> template<class selfT, unsigned int dimT>
    struct	kazu::blast<typeT>::vecproto<selfT, dimT> :
    	public boost::arithmetic< selfT, 
    		boost::multiplicative< selfT, typeT,
    		kazu::unary<selfT, typeT, dimT,
    		kazu::binary<selfT, typeT, dimT,
    		kazu::trinary<selfT, typeT, dimT
    	> > > > >
    {
    //	selfT(typeT a[dimT])	{	for (unsigned i = 0; i < dimT; i++){ this->_a[i] = a[i]; }	}
     
    	//sum
    	inline	typeT	sum()	{	typeT rv = (typeT)0;	for(unsigned int i = 0; i < dimT; i++){rv += this->_a[i];}	return rv;	}
     
    	//dot
    	virtual	typeT	dot(const selfT& b)	{	selfT rv(*this); rv *= b; return rv.sum(); 	}
    	inline	friend	typeT	dot(const selfT& a, const selfT& b)	{	return a.dot(b);	}
     
    	//cross
    //	virtual	selfT	cross(const selfT& b);	//todo: implement in specialization
    	inline	friend	selfT	cross(const selfT& a, const selfT& b)	{	return a.cross(b);	}
     
    	//length
    	inline	typeT	lensq()	{	selfT a(*this); a *= a; return a.sum();		}
    	inline	friend	typeT	lensq(const selfT& a)	{	return	a.lensq();	}
     
    	inline	typeT	length()	{	return std::sqrt<typeT>( lensq() );		}
    	inline	friend	typeT	length(const selfT& a)	{	return a.length();	}
     
    	inline	typeT	distance(const selfT& rhv)	{	selfT a = rhv - (*this); return a.length();	}
    	inline	friend	typeT distance(const selfT& a, const selfT& b)	{	return a.distance(b);	}
     
    	//operators
    	virtual	selfT&	operator=(const selfT& b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] = b._a[i];	}	}
    	virtual	selfT&	operator+=(const selfT& b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] += b._a[i];	}	}
    	virtual	selfT&	operator-=(const selfT& b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] -= b._a[i];	}	}
    	virtual	selfT&	operator*=(const selfT& b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] *= b._a[i];	}	}
    	virtual	selfT&	operator/=(const selfT& b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] /= b._a[i];	}	}
     
    	virtual	selfT&	operator*=(const typeT b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] *= b;	}	}
    	virtual	selfT&	operator/=(const typeT b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] /= b;	}	}
     
    	//this ought to crash the compiler, or at least induce errors
    //	selfT&	operator+=(const selfT& b)	{	(*this) = (*this) + b;	}
    //	selfT&	operator-=(const selfT& b)	{	(*this) = (*this) - b;	}
    //	selfT&	operator*=(const selfT& b)	{	(*this) = (*this) * b;	}
    //	selfT&	operator/=(const selfT& b)	{	(*this) = (*this) / b;	}
     
    	inline	typeT&		operator[](unsigned int idx)	{	assert(idx < dimT); return this->_a[idx];	}
    	inline	operator	typeT*()						{	return &this->_a[0];	}
     
    	//swizzle
    	template<unsigned int X>	inline	typeT&			get()		{	BOOST_STATIC_ASSERT(X < dimT); return this->_a[X];	}
    	template<unsigned int X>	inline	const typeT&	get() const	{	BOOST_STATIC_ASSERT(X < dimT); return this->_a[X];	}
     
    	template<unsigned int X, unsigned int Y>
    	vec2 swizzle2();
    	template<unsigned int X, unsigned int Y>
    	const vec2 swizzle2() const ;
     
    	template<unsigned int X, unsigned int Y, unsigned int Z>
    	vec3 swizzle3();
    	template<unsigned int X, unsigned int Y, unsigned int Z>
    	const vec3 swizzle3() const;
     
    	template<unsigned int X, unsigned int Y, unsigned int Z, unsigned int W>
    	vec4 swizzle4();
    	template<unsigned int X, unsigned int Y, unsigned int Z, unsigned int W>
    	const vec4 swizzle4() const;
     
    	std::ostream& operator<<(std::ostream& os)
    	{
    		os << "vec" << dimT << " [";
    		for(unsigned int i = 0; i < dimT; i++)
    		{	
    			if(i)
    				os << ", ";
    			os << (*this)[i];			
    		}
    		os << "]";
    		return os;
    	}
    };
     
    //////////////////////////////////////////////////////////////////////////
    //specialization of cross()
     
    /*
    template<typename typeT> template<class selfT>
    selfT	kazu::blast<typeT>::vecproto<selfT, 2>::cross(const selfT& rhv)
    {
    	selfT rv;
    	//not sure, should return 0, 0
    	rv.x = this->x * rhv.y;
    	rv.y = this->y * rhv.x;
    	return rv;
    }
     
     
    template<typename typeT> template<class selfT>
    selfT	kazu::blast<typeT>::vecproto<selfT, 3>::cross(const selfT& rhv)
    {
    	selfT rv;
    	rv.x = this->y * rhv.z - this->z * rhv.y;
    	rv.y = this->y * rhv.z - this->z * rhv.y;
    	rv.z = this->y * rhv.z - this->z * rhv.y;
    	return rv;
    }
     
     
    template<typename typeT> template<class selfT>
    selfT	kazu::blast<typeT>::vecproto<selfT, 4>::cross(const selfT& rhv)
    {
    	selfT rv;
    	rv.x = this->y * rhv.z - this->z * rhv.y;
    	rv.y = this->y * rhv.z - this->z * rhv.y;
    	rv.z = this->y * rhv.z - this->z * rhv.y;
    	rv.w = this->w * rhv.w;		//not sure about this one
     
    //4D cross
    //	rv.x = this->y * rhv.z - this->z * rhv.y + this->z * rhv.w - this->w * rhv.z + this->y * rhv.w - this->w * rhv.y;
    //	rv.y = this->z * rhv.x - this->x * rhv.z + this->w * rhv.x - this->x * rhv.w + this->z * rhv.w - this->w * rhv.z;
    //	rv.z = this->x * rhv.y - this->y * rhv.x + this->w * rhv.y - this->y * rhv.w + this->w * rhv.x - this->x * rhv.w;
    //	rv.w = this->x * rhv.y - this->y * rhv.x + this->y * rhv.z - this->z * rhv.y + this->x * rhv.z - this->z * rhv.x;
     
    	return rv;
    }
    */
     
    //////////////////////////////////////////////////////////////////////////
    //definition of vec classes
     
    template<typename typeT>
    struct kazu::blast<typeT>::vec2 : public kazu::blast<typeT>::vecproto<vec2, 2>
    {
    	union
    	{
    		typeT	_a[2];
    		struct { typeT x, y; };
    		struct { typeT i, a; };
    		struct { typeT s, t; };
    		struct { typeT _0, _1; };		
    	};
     
    	vec2()	{}	
    	vec2(const vec2& b): x(b.x), y(b.y)	{}
    	vec2(typeT _x, typeT _y): x(_x), y(_y)	{}	
    	virtual ~vec2(){}
     
    	//todo: declare swizzle functions here
    	vec2	xx();
    	vec3	xxx();
    	vec4	xxxx();
     
    	const	vec2	xx()	const;
    	const	vec3	xxx()	const;
    	const	vec4	xxxx()	const;
    };
     
    template<typename typeT>
    struct kazu::blast<typeT>::vec3 : public kazu::blast<typeT>::vecproto<vec3, 3>
    {
    	union
    	{
    		typeT	_a[3];
    		struct { typeT x, y, z; };
    		struct { typeT r, g, b; };
    		struct { typeT s, t, p; };
    		struct { typeT _0, _1, _2; };		
    	};
     
    	vec3()	{}	
    	vec3(const vec3& b): x(b.x), y(b.y), z(b.z)	{}
    	vec3(typeT _x, typeT _y, typeT _z): x(_x), y(_y), z(_z)	{}	
    	vec3(const vec2& b): x(b.x), y(b.y), z((typeT)0)	{}
    	virtual ~vec3(){}
     
    	//todo: declare swizzle functions here
    	vec2	xx();
    	vec3	xxx();
    	vec4	xxxx();
     
    	const	vec2	xx()	const;
    	const	vec3	xxx()	const;
    	const	vec4	xxxx()	const;
    };
     
    template<typename typeT>
    struct kazu::blast<typeT>::vec4 : public kazu::blast<typeT>::vecproto<vec4, 4>
    {
    	union
    	{
    		typeT	_a[4];
    		struct { typeT x, y, z, w; };
    		struct { typeT r, g, b, a; };
    		struct { typeT s, t, p, q; };
    		struct { typeT _0, _1, _2, _3; };		
    	};
     
    	vec4()	{}	
    	vec4(const vec4& b): x(b.x), y(b.y), z(b.z), w(b.w)	{}
    	vec4(typeT _x, typeT _y, typeT _z, typeT _w): x(_x), y(_y), z(_z), w(_w)	{}	
    	vec4(const vec2& b): x(b.x), y(b.y), z((typeT)0), w((typeT)1)	{}
    	vec4(const vec3& b): x(b.x), y(b.y), z(b.z), w((typeT)1)		{}
    	virtual ~vec4(){}
     
    	//todo: declare swizzle functions here
    	vec2	xx();
    	vec3	xxx();
    	vec4	xxxx();
     
    	const	vec2	xx()	const;
    	const	vec3	xxx()	const;
    	const	vec4	xxxx()	const;
    };
     
     
    template<typename typeT>
    struct kazu::blast<typeT>::vec4D : kazu::blast<typeT>::vec4
    {
    };
     
    //////////////////////////////////////////////////////////////////////////
    //definition of swizzle functions
     
    template<typename typeT> template<class selfT, unsigned int dimT> template<unsigned int X, unsigned int Y>
    inline	kazu::blast<typeT>::vec2
    kazu::blast<typeT>::vecproto<selfT, dimT>::swizzle2<X, Y>()
    {	return kazu::blast<typeT>::vec2(this->get<X>(), this->get<Y>());	}
     
    template<typename typeT> template<class selfT, unsigned int dimT> template<unsigned int X, unsigned int Y>
    inline	const kazu::blast<typeT>::vec2
    kazu::blast<typeT>::vecproto<selfT, dimT>::swizzle2<X, Y>() const
    {	return kazu::blast<typeT>::vec2(this->get<X>(), this->get<Y>());	}
     
     
    template<typename typeT> template<class selfT, unsigned int dimT> template<unsigned int X, unsigned int Y, unsigned int Z>
    inline	kazu::blast<typeT>::vec3
    kazu::blast<typeT>::vecproto<selfT, dimT>::swizzle3<X, Y, Z>()
    {	return kazu::blast<typeT>::vec3(this->get<X>(), this->get<Y>(), this->get<Z>());	}
     
    template<typename typeT> template<class selfT, unsigned int dimT> template<unsigned int X, unsigned int Y, unsigned int Z>
    inline	const kazu::blast<typeT>::vec3
    kazu::blast<typeT>::vecproto<selfT, dimT>::swizzle3<X, Y, Z>() const
    {	return kazu::blast<typeT>::vec3(this->get<X>(), this->get<Y>(), this->get<Z>());	}
     
     
    template<typename typeT> template<class selfT, unsigned int dimT> template<unsigned int X, unsigned int Y, unsigned int Z, unsigned int W>
    inline	kazu::blast<typeT>::vec4
    kazu::blast<typeT>::vecproto<selfT, dimT>::swizzle4<X, Y, Z, W>()
    {	return kazu::blast<typeT>::vec4(this->get<X>(), this->get<Y>(), this->get<Z>(), this->get<W>());	}
     
    template<typename typeT> template<class selfT, unsigned int dimT, unsigned int X> template<unsigned int Y, unsigned int Z, unsigned int W>
    inline	const kazu::blast<typeT>::vec4
    kazu::blast<typeT>::vecproto<selfT, dimT>::swizzle4<X, Y, Z, W>() const
    {	return kazu::blast<typeT>::vec4(this->get<X>(), this->get<Y>(), this->get<Z>(), this->get<W>());	}
     
    //////////////////////////////////////////////////////////////////////////
    //definition of swizzle functions
    template<typename typeT>
    kazu::blast<typeT>::vec2	kazu::blast<typeT>::vec2::xx()
    {	return	this->swizzle2<0, 0>();		}
     
    template<typename typeT>
    kazu::blast<typeT>::vec3	kazu::blast<typeT>::vec2::xxx()
    {	return	this->swizzle3<0, 0, 0>();		}
     
    template<typename typeT>
    kazu::blast<typeT>::vec4	kazu::blast<typeT>::vec2::xxxx()
    {	return	this->swizzle4<0, 0, 0, 0>();		}
     
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec2	kazu::blast<typeT>::vec2::xx()	const
    {	return	this->swizzle2<0, 0>();		}
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec3	kazu::blast<typeT>::vec2::xxx()	const
    {	return	this->swizzle3<0, 0, 0>();		}
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec4	kazu::blast<typeT>::vec2::xxxx()const
    {	return	this->swizzle4<0, 0, 0, 0>();		}
     
     
    template<typename typeT>
    kazu::blast<typeT>::vec2	kazu::blast<typeT>::vec3::xx()
    {	return	this->swizzle2<0, 0>();		}
     
    template<typename typeT>
    kazu::blast<typeT>::vec3	kazu::blast<typeT>::vec3::xxx()
    {	return	this->swizzle3<0, 0, 0>();		}
     
    template<typename typeT>
    kazu::blast<typeT>::vec4	kazu::blast<typeT>::vec3::xxxx()
    {	return	this->swizzle4<0, 0, 0, 0>();		}
     
     
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec2	kazu::blast<typeT>::vec3::xx()	const
    {	return	this->swizzle2<0, 0>();		}
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec3	kazu::blast<typeT>::vec3::xxx()	const
    {	return	this->swizzle3<0, 0, 0>();		}
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec4	kazu::blast<typeT>::vec3::xxxx()const
    {	return	this->swizzle4<0, 0, 0, 0>();		}
     
     
    template<typename typeT>
    kazu::blast<typeT>::vec2	kazu::blast<typeT>::vec4::xx()
    {	return	this->swizzle2<0, 0>();		}
     
    template<typename typeT>
    kazu::blast<typeT>::vec3	kazu::blast<typeT>::vec4::xxx()
    {	return	this->swizzle3<0, 0, 0>();		}
     
    template<typename typeT>
    kazu::blast<typeT>::vec4	kazu::blast<typeT>::vec4::xxxx()
    {	return	this->swizzle4<0, 0, 0, 0>();		}
     
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec2	kazu::blast<typeT>::vec4::xx()	const
    {	return	this->swizzle2<0, 0>();		}
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec3	kazu::blast<typeT>::vec4::xxx()	const
    {	return	this->swizzle3<0, 0, 0>();		}
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec4	kazu::blast<typeT>::vec4::xxxx()const
    {	return	this->swizzle4<0, 0, 0, 0>();		}
     
    //////////////////////////////////////////////////////////////////////////
     
    int main(int argc, char** argv)
    {
    	kazu::blast<float>::vec4 a4(1f, 2f, 3f, 1f);
     
    	std::cout << a4 << std::endl;
    	return 0;
    }
     
    //////////////////////////////////////////////////////////////////////////

    et l'erreur principal: ';' manquant à cette ligne (celle en gras)
    template<typename typeT> template<class selfT, unsigned int dimT> template<unsigned int X, unsigned int Y>
    inline kazu::blast<typeT>::vec2
    kazu::blast<typeT>::vecproto<selfT, dimT>::swizzle2<X, Y>()
    { return kazu::blast<typeT>::vec2(this->get<X>(), this->get<Y>()); }


    là, je vois vraiment pas ou j'ai pu oublier un semicolon, regardez le code source, c'est bien correct, non?

    EDIT: ah oui, l'autre erreur, c'est la définition de la fonction "cross" que j'ai mise en commentaire actuellement.

  4. #4
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Ouf!, le gros bout de code heureusement que j'ai l'estomac solide !

    Il me semble que contrairement au classes (ou structures) Template, les fonctions template doivent obligatoirement prendre en argument l'intégralité de leurs paramètres template.

    Sauf que normalement, ça ne pose pas de problème avec les constante

    Par contre, il me semble que la syntaxe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template<class C1,...>Maclasse<C1>
    ne s'applique pas pour les fonctions: ce serait plutot:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template<class C1,...>Mafonction(C1)
    je crois donc que l'erreur, de syntaxe une fois encore est qu'il faut mettre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    kazu::blast<typeT>::vecproto<selfT, dimT>::swizzle2()
    à la place de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    kazu::blast<typeT>::vecproto<selfT, dimT>::swizzle2<X, Y>()
    Pra contre, comme tu a ce genre de syntaxe un certain nombre de fois, tu aura à mon avis pas mal de remplacements à faire...


    Enfin, sache que si tu as des fonction virtuelles dans les classes dont tu hérite, je crois qu'elles se comporterons comme des fonction normales.

    J'espère que la 1ere solution est la bonne par-ce que sinon, je serait chauve demain

    Sinon, tu peut me donner l'erreur renvoyée à cross ? Je m'y attaque tout de suite.

    Bonne chance et tient nous au courant


    PS: Tu développe pour quoi ton open source ?
    PS2: je ne peut pas tester ton code, je n'ai pas boost

    EDIT: Pour Cross, la seule chose que je voie est qu'il est déclaré virtuel... peut être qu'il faut aussi utiliser le mot clé virtual lors de la declaration externe de celui-ci... Enfin, je n'ai pas fait beaucoup d'héritage, donc je ne sait pas trop...
    Sinon, Tu à bien pensé à uncommenter la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    //	virtual	selfT	cross(const selfT& b);	//todo: implement in specialization
    dans la déclaration de vecproto hein ?
    Méphistophélès
    Si la solution ne résout pas votre problème, changez le problème...
    Cours et tutoriels C++ - FAQ C++ - Forum C++.

  5. #5
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    Ben, je veux que la fonction "cross" soit virtuelle, justement parce que je pense dériver des classes de la classe vec pour permettre des optimisations dépendantes du processeur (SIMD, Altivec,...) et du type de base (du genre, juste optimiser les calculs pour les floats).

  6. #6
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    heu... mais la corection précédente marche ?

    et tu a essayé de déclarer tes fonctions virtual à l'exterieur ?

    et tu n'a pas répondu à mes question
    Méphistophélès
    Si la solution ne résout pas votre problème, changez le problème...
    Cours et tutoriels C++ - FAQ C++ - Forum C++.

  7. #7
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    Salut,

    en fait, ta méthode d'enlever le <> à l'utilisation de la fonction n'a pas fonctionné (ou alors, je m'y suis mal pris...) mais ce qui a fonctionné, c'était de mettre la définition de la fonction swizzle2 directement dans le corps de la structure templatisé, donc à l'intérieur du template<typeT>. Ca fonctionne, à condition de placer les définitions des structures vec avant la défintion du template vecproto (pas très élégant, mais du moment que ca fonctionne).


    L'erreur que j'ai avec 'cross', c'est ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    error C2039: 'cross': n'est pas un element de 'kazu::blast<scalarT>::vecproto<selfT,2>'
     
    error C2039: 'cross': n'est pas un element de 'kazu::blast<scalarT>::vecproto<selfT,3>'
     
    error C2039: 'cross': n'est pas un element de 'kazu::blast<scalarT>::vecproto<selfT,4>'

    Vu que j'ai un peu remanié le code, le voici à nouveau:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    //!     \file   Kazu.cpp
    //!     @brief  fast test for kazu
     
     
    //---------------------------------------------------------------------------
    //Boost.asserts
    #include <boost/static_assert.hpp>
     
    //Boost.operators
    #include <boost/operators.hpp>
     
    //SL.Math
    #include <cmath>
     
    //SL.assert
    #include <cassert>
     
    //STL.cout
    #include <iostream>
    //////////////////////////////////////////////////////////////////////////
    //forward declaration 
     
    namespace kazu
    {
    	template<typename scalarT>
    	struct	blast
    	{
    		//vec fwd decl
    		class	vec2;
    		class	vec3;
    		class	vec4;
    		class	vec4D;
     
    		//mat fwd decl
    		class	mat2x2;
    		class	mat2x3;
    		class	mat2x4;
     
    		class	mat3x2;
    		class	mat3x3;
    		class	mat3x4;
     
    		class	mat4x2;
    		class	mat4x3;
    		class	mat4x4;
     
    		//other fwd decl: complex, hypercomplex
    		class	complex;
    		class	quaternion;
    		class	octonion;
     
    		//typedefs
    		typedef	scalarT	scalar;
    		typedef	mat2x2	mat2;
    		typedef	mat3x3	mat3;
    		typedef	mat4x4	mat4;
     
    		//utility classes
    		template<class vecT, unsigned int sizeT>
    		class	vecproto;
     
    		template<class matT, class transT, unsigned int sizeA, unsigned int sizeB>
    		class	matproto;
    	};
    }//namespace kazu
     
    //////////////////////////////////////////////////////////////////////////
    //vecproto - template definition
     
    namespace kazu
    {
    	template<class selfT, typename typeT, unsigned int dimT, class B = ::boost::detail::empty_base<selfT> >
    	struct	unary : B
    	{
    		friend	selfT	sin(const selfT& a)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)sin( a._a[i] );	}	return rv;	}
    		friend	selfT	cos(const selfT& a)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)cps( a._a[i] );	}	return rv;	}
    		friend	selfT	tan(const selfT& a)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)tan( a._a[i] );	}	return rv;	}
    		friend	selfT	asin(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)asin( a._a[i] );	}	return rv;	}
    		friend	selfT	acos(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)acos( a._a[i] );	}	return rv;	}
    		friend	selfT	atan(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)atan( a._a[i] );	}	return rv;	}
    		friend	selfT	exp(const selfT& a)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)exp( a._a[i] );	}	return rv;	}
    		friend	selfT	log(const selfT& a)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)log( a._a[i] );	}	return rv;	}
    		friend	selfT	exp2(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)exp2( a._a[i] );	}	return rv;	}
    		friend	selfT	log2(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)log2( a._a[i] );	}	return rv;	}
    		friend	selfT	sqrt(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)sqrt( a._a[i] );	}	return rv;	}
    		friend	selfT	abs(const selfT& a)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)abs( a._a[i] );	}	return rv;	}
    		friend	selfT	sign(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)sign( a._a[i] );	}	return rv;	}
    		friend	selfT	floor(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)floor( a._a[i] );	}	return rv;	}
    		friend	selfT	ceil(const selfT& a)	{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)ceil( a._a[i] );	}	return rv;	}		
    	};
     
    	template<class selfT, typename typeT, unsigned int dimT, class B = ::boost::detail::empty_base<selfT> >
    	struct	binary : B
    	{
    		friend	selfT	pow(const selfT& a, const selfT& b)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)pow( a._a[i], b._a[i] );	}	return rv;	}
    		friend	selfT	pow(const selfT& a, const typeT b)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)pow( a._a[i], b );	}	return rv;	}
     
    		friend	selfT	min(const selfT& a, const selfT& b)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)min( a._a[i], b._a[i] );	}	return rv;	}
    		friend	selfT	max(const selfT& a, const selfT& b)		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)max( a._a[i], b._a[i] );	}	return rv;	}
    	};
     
    	template<class selfT, typename typeT, unsigned int dimT, class B = ::boost::detail::empty_base<selfT> >
    	struct	trinary : B
    	{
    		friend	selfT	clamp(const selfT& a, const selfT& b, const selfT& c)		
    		{	selfT rv(a);	for(unsigned int i = 0; i < dimT; i++){	rv._a[i] = (typeT)clamp( a._a[i], b._a[i], c._a[i] );	}	return rv;	}
    	};
    }
     
     
    //////////////////////////////////////////////////////////////////////////
    //definition of vec classes
     
    template<typename typeT>
    struct kazu::blast<typeT>::vec2 : public kazu::blast<typeT>::vecproto<vec2, 2>
    {
    	union
    	{
    		typeT	_a[2];
    		struct { typeT x, y; };
    		struct { typeT i, a; };
    		struct { typeT s, t; };
    		struct { typeT _0, _1; };		
    	};
     
    	vec2()	{}	
    	vec2(const vec2& b): x(b.x), y(b.y)	{}
    	vec2(const vecproto<vec2, 2>& b){}
    	vec2(typeT _x, typeT _y): x(_x), y(_y)	{}	
    	virtual ~vec2(){}
     
    	//todo: declare swizzle functions here
    	vec2	xx();
    	vec3	xxx();
    	vec4	xxxx();
     
    	const	vec2	xx()	const;
    	const	vec3	xxx()	const;
    	const	vec4	xxxx()	const;
    };
     
    template<typename typeT>
    struct kazu::blast<typeT>::vec3 : public kazu::blast<typeT>::vecproto<vec3, 3>
    {
    	union
    	{
    		typeT	_a[3];
    		struct { typeT x, y, z; };
    		struct { typeT r, g, b; };
    		struct { typeT s, t, p; };
    		struct { typeT _0, _1, _2; };		
    	};
     
    	vec3()	{}	
    	vec3(const vec3& b): x(b.x), y(b.y), z(b.z)	{}
    	vec3(const vecproto<vec3, 3>& b){}
    	vec3(typeT _x, typeT _y, typeT _z): x(_x), y(_y), z(_z)	{}	
    	vec3(const vec2& b): x(b.x), y(b.y), z((typeT)0)	{}
    	virtual ~vec3(){}
     
    	//todo: declare swizzle functions here
    	vec2	xx();
    	vec3	xxx();
    	vec4	xxxx();
     
    	const	vec2	xx()	const;
    	const	vec3	xxx()	const;
    	const	vec4	xxxx()	const;
    };
     
    template<typename typeT>
    struct kazu::blast<typeT>::vec4 : public kazu::blast<typeT>::vecproto<vec4, 4>
    {
    	union
    	{
    		typeT	_a[4];
    		struct { typeT x, y, z, w; };
    		struct { typeT r, g, b, a; };
    		struct { typeT s, t, p, q; };
    		struct { typeT _0, _1, _2, _3; };		
    	};
     
    	vec4()	{}	
    	vec4(const vec4& b): x(b.x), y(b.y), z(b.z), w(b.w)	{}
    	vec4(const vecproto<vec4, 4>& b){}
    	vec4(typeT _x, typeT _y, typeT _z, typeT _w): x(_x), y(_y), z(_z), w(_w)	{}	
    	vec4(const vec2& b): x(b.x), y(b.y), z((typeT)0), w((typeT)1)	{}
    	vec4(const vec3& b): x(b.x), y(b.y), z(b.z), w((typeT)1)		{}
    	virtual ~vec4(){}
     
    	//todo: declare swizzle functions here
    	vec2	xx();
    	vec3	xxx();
    	vec4	xxxx();
     
    	const	vec2	xx()	const;
    	const	vec3	xxx()	const;
    	const	vec4	xxxx()	const;
    };
     
     
    template<typename typeT>
    struct kazu::blast<typeT>::vec4D : kazu::blast<typeT>::vec4
    {
    };
     
    //////////////////////////////////////////////////////////////////////////
     
    template<typename typeT> template<class selfT, unsigned int dimT>
    struct	kazu::blast<typeT>::vecproto<selfT, dimT> :
    	public boost::arithmetic< selfT, 
    		boost::multiplicative< selfT, typeT,
    		kazu::unary<selfT, typeT, dimT,
    		kazu::binary<selfT, typeT, dimT,
    		kazu::trinary<selfT, typeT, dimT
    	> > > > >
    {
    //	selfT(typeT a[dimT])	{	for (unsigned i = 0; i < dimT; i++){ this->_a[i] = a[i]; }	}
     
    	//sum
    	inline	typeT	sum()	{	typeT rv = (typeT)0;	for(unsigned int i = 0; i < dimT; i++){rv += this->_a[i];}	return rv;	}
     
    	//dot
    	virtual	typeT	dot(const selfT& b)	{	selfT rv(*this); rv *= b; return rv.sum(); 	}
    	inline	friend	typeT	dot(const selfT& a, const selfT& b)	{	return a.dot(b);	}
     
    	//cross
    	virtual	selfT	cross(const selfT& b);	//todo: implement in specialization
    	inline	friend	selfT	cross(const selfT& a, const selfT& b)	{	return a.cross(b);	}
     
    	//length
    	inline	typeT	lensq()	{	selfT a(*this); a *= a; return a.sum();		}
    	inline	friend	typeT	lensq(const selfT& a)	{	return	a.lensq();	}
     
    	inline	typeT	length()	{	return std::sqrt<typeT>( lensq() );		}
    	inline	friend	typeT	length(const selfT& a)	{	return a.length();	}
     
    	inline	typeT	distance(const selfT& rhv)	{	selfT a = rhv - (*this); return a.length();	}
    	inline	friend	typeT distance(const selfT& a, const selfT& b)	{	return a.distance(b);	}
     
    	//operators
    	virtual	selfT&	operator=(const selfT& b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] = b._a[i];	}	}
    	virtual	selfT&	operator+=(const selfT& b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] += b._a[i];	}	}
    	virtual	selfT&	operator-=(const selfT& b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] -= b._a[i];	}	}
    	virtual	selfT&	operator*=(const selfT& b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] *= b._a[i];	}	}
    	virtual	selfT&	operator/=(const selfT& b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] /= b._a[i];	}	}
     
    	virtual	selfT&	operator*=(const typeT b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] *= b;	}	}
    	virtual	selfT&	operator/=(const typeT b)	{	for(unsigned int i = 0; i < dimT; i++){this->_a[i] /= b;	}	}
     
    	//this ought to crash the compiler, or at least induce errors
    //	selfT&	operator+=(const selfT& b)	{	(*this) = (*this) + b;	}
    //	selfT&	operator-=(const selfT& b)	{	(*this) = (*this) - b;	}
    //	selfT&	operator*=(const selfT& b)	{	(*this) = (*this) * b;	}
    //	selfT&	operator/=(const selfT& b)	{	(*this) = (*this) / b;	}
     
    	inline	typeT&		operator[](unsigned int idx)	{	assert(idx < dimT); return this->_a[idx];	}
    	inline	operator	typeT*()						{	return &this->_a[0];	}
     
    	//swizzle
    	template<unsigned int X>	inline	typeT&			get()		{	BOOST_STATIC_ASSERT(X < dimT); return this->_a[X];	}
    	template<unsigned int X>	inline	const typeT&	get() const	{	BOOST_STATIC_ASSERT(X < dimT); return this->_a[X];	}
     
    	template<unsigned int X, unsigned int Y>
    	inline	vec2 swizzle2() 
    	{	return vec2(this->get<X>(), this->get<Y>());	}
     
    	template<unsigned int X, unsigned int Y>
    	inline	const vec2 swizzle2() const
    	{	return vec2(this->get<X>(), this->get<Y>());	}
     
     
    	template<unsigned int X, unsigned int Y, unsigned int Z>
    	inline	vec3 swizzle3()
    	{	return vec3(this->get<X>(), this->get<Y>(), this->get<Z>());	}
     
    	template<unsigned int X, unsigned int Y, unsigned int Z>
    	inline	const vec3 swizzle3() const
    	{	return vec3(this->get<X>(), this->get<Y>(), this->get<Z>());	}
     
    	template<unsigned int X, unsigned int Y, unsigned int Z, unsigned int W>
    	inline	vec4 swizzle4()
    	{	return vec4(this->get<X>(), this->get<Y>(), this->get<Z>(), this->get<W>());	}
     
    	template<unsigned int X, unsigned int Y, unsigned int Z, unsigned int W>
    	inline	const vec4 swizzle4() const
    	{	return vec4(this->get<X>(), this->get<Y>(), this->get<Z>(), this->get<W>());	}
     
    	std::ostream& operator<<(std::ostream& os)
    	{
    		os << "vec" << dimT << " [";
    		for(unsigned int i = 0; i < dimT; i++)
    		{	
    			if(i)
    				os << ", ";
    			os << (*this)[i];			
    		}
    		os << "]";
    		return os;
    	}
    };
     
    //////////////////////////////////////////////////////////////////////////
    //specialization of cross()
     
     
    template<typename typeT> template<class selfT>
    selfT	kazu::blast<typeT>::vecproto<selfT, 2>::cross(const selfT& rhv)
    {
    	selfT rv;
    	//not sure, should return 0, 0
    	rv.x = this->x * rhv.y;
    	rv.y = this->y * rhv.x;
    	return rv;
    }
     
     
    template<typename typeT> template<class selfT>
    selfT	kazu::blast<typeT>::vecproto<selfT, 3>::cross(const selfT& rhv)
    {
    	selfT rv;
    	rv.x = this->y * rhv.z - this->z * rhv.y;
    	rv.y = this->y * rhv.z - this->z * rhv.y;
    	rv.z = this->y * rhv.z - this->z * rhv.y;
    	return rv;
    }
     
     
    template<typename typeT> template<class selfT>
    selfT	kazu::blast<typeT>::vecproto<selfT, 4>::cross(const selfT& rhv)
    {
    	selfT rv;
    	rv.x = this->y * rhv.z - this->z * rhv.y;
    	rv.y = this->y * rhv.z - this->z * rhv.y;
    	rv.z = this->y * rhv.z - this->z * rhv.y;
    	rv.w = this->w * rhv.w;		//not sure about this one
     
    //4D cross
    //	rv.x = this->y * rhv.z - this->z * rhv.y + this->z * rhv.w - this->w * rhv.z + this->y * rhv.w - this->w * rhv.y;
    //	rv.y = this->z * rhv.x - this->x * rhv.z + this->w * rhv.x - this->x * rhv.w + this->z * rhv.w - this->w * rhv.z;
    //	rv.z = this->x * rhv.y - this->y * rhv.x + this->w * rhv.y - this->y * rhv.w + this->w * rhv.x - this->x * rhv.w;
    //	rv.w = this->x * rhv.y - this->y * rhv.x + this->y * rhv.z - this->z * rhv.y + this->x * rhv.z - this->z * rhv.x;
     
    	return rv;
    }
     
     
     
     
     
     
     
     
    //////////////////////////////////////////////////////////////////////////
    //definition of swizzle functions
    /*
    template<typename typeT> template<class selfT, unsigned int dimT> template<unsigned int X, unsigned int Y>
    inline	kazu::blast<typeT>::vec2
    kazu::blast<typeT>::vecproto<selfT, dimT>::swizzle2<X, Y>()
    {	return kazu::blast<typeT>::vec2(this->get<X>(), this->get<Y>());	}
     
    template<typename typeT> template<class selfT, unsigned int dimT> template<unsigned int X, unsigned int Y>
    inline	const kazu::blast<typeT>::vec2
    kazu::blast<typeT>::vecproto<selfT, dimT>::swizzle2<X, Y>() const
    {	return kazu::blast<typeT>::vec2(this->get<X>(), this->get<Y>());	}
     
     
    template<typename typeT> template<class selfT, unsigned int dimT> template<unsigned int X, unsigned int Y, unsigned int Z>
    inline	kazu::blast<typeT>::vec3
    kazu::blast<typeT>::vecproto<selfT, dimT>::swizzle3<X, Y, Z>()
    {	return kazu::blast<typeT>::vec3(this->get<X>(), this->get<Y>(), this->get<Z>());	}
     
    template<typename typeT> template<class selfT, unsigned int dimT> template<unsigned int X, unsigned int Y, unsigned int Z>
    inline	const kazu::blast<typeT>::vec3
    kazu::blast<typeT>::vecproto<selfT, dimT>::swizzle3<X, Y, Z>() const
    {	return kazu::blast<typeT>::vec3(this->get<X>(), this->get<Y>(), this->get<Z>());	}
     
     
    template<typename typeT> template<class selfT, unsigned int dimT> template<unsigned int X, unsigned int Y, unsigned int Z, unsigned int W>
    inline	kazu::blast<typeT>::vec4
    kazu::blast<typeT>::vecproto<selfT, dimT>::swizzle4<X, Y, Z, W>()
    {	return kazu::blast<typeT>::vec4(this->get<X>(), this->get<Y>(), this->get<Z>(), this->get<W>());	}
     
    template<typename typeT> template<class selfT, unsigned int dimT, unsigned int X> template<unsigned int Y, unsigned int Z, unsigned int W>
    inline	const kazu::blast<typeT>::vec4
    kazu::blast<typeT>::vecproto<selfT, dimT>::swizzle4<X, Y, Z, W>() const
    {	return kazu::blast<typeT>::vec4(this->get<X>(), this->get<Y>(), this->get<Z>(), this->get<W>());	}
    */
    //////////////////////////////////////////////////////////////////////////
    //definition of swizzle functions
    /*
    template<typename typeT>
    kazu::blast<typeT>::vec2	kazu::blast<typeT>::vec2::xx()
    {	return	this->swizzle2<0, 0>();		}
     
    template<typename typeT>
    kazu::blast<typeT>::vec3	kazu::blast<typeT>::vec2::xxx()
    {	return	this->swizzle3<0, 0, 0>();		}
     
    template<typename typeT>
    kazu::blast<typeT>::vec4	kazu::blast<typeT>::vec2::xxxx()
    {	return	this->swizzle4<0, 0, 0, 0>();		}
     
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec2	kazu::blast<typeT>::vec2::xx()	const
    {	return	this->swizzle2<0, 0>();		}
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec3	kazu::blast<typeT>::vec2::xxx()	const
    {	return	this->swizzle3<0, 0, 0>();		}
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec4	kazu::blast<typeT>::vec2::xxxx()const
    {	return	this->swizzle4<0, 0, 0, 0>();		}
     
     
    template<typename typeT>
    kazu::blast<typeT>::vec2	kazu::blast<typeT>::vec3::xx()
    {	return	this->swizzle2<0, 0>();		}
     
    template<typename typeT>
    kazu::blast<typeT>::vec3	kazu::blast<typeT>::vec3::xxx()
    {	return	this->swizzle3<0, 0, 0>();		}
     
    template<typename typeT>
    kazu::blast<typeT>::vec4	kazu::blast<typeT>::vec3::xxxx()
    {	return	this->swizzle4<0, 0, 0, 0>();		}
     
     
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec2	kazu::blast<typeT>::vec3::xx()	const
    {	return	this->swizzle2<0, 0>();		}
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec3	kazu::blast<typeT>::vec3::xxx()	const
    {	return	this->swizzle3<0, 0, 0>();		}
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec4	kazu::blast<typeT>::vec3::xxxx()const
    {	return	this->swizzle4<0, 0, 0, 0>();		}
     
     
    template<typename typeT>
    kazu::blast<typeT>::vec2	kazu::blast<typeT>::vec4::xx()
    {	return	this->swizzle2<0, 0>();		}
     
    template<typename typeT>
    kazu::blast<typeT>::vec3	kazu::blast<typeT>::vec4::xxx()
    {	return	this->swizzle3<0, 0, 0>();		}
     
    template<typename typeT>
    kazu::blast<typeT>::vec4	kazu::blast<typeT>::vec4::xxxx()
    {	return	this->swizzle4<0, 0, 0, 0>();		}
     
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec2	kazu::blast<typeT>::vec4::xx()	const
    {	return	this->swizzle2<0, 0>();		}
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec3	kazu::blast<typeT>::vec4::xxx()	const
    {	return	this->swizzle3<0, 0, 0>();		}
     
    template<typename typeT>
    const	kazu::blast<typeT>::vec4	kazu::blast<typeT>::vec4::xxxx()const
    {	return	this->swizzle4<0, 0, 0, 0>();		}
    */
    //////////////////////////////////////////////////////////////////////////
     
    int main(int argc, char** argv)
    {
    	kazu::blast<float>::vec4 a4(1.0f, 2.0f, 3.0f, 1.0f);
     
    	std::cout << a4 << std::endl;
    	return 0;
    }
     
    //////////////////////////////////////////////////////////////////////////
    Pour répondre à question dans quel but je crée cette lib, c'est simple, ce sera ma lib de base pour tout ce qui est algorithmique/algèbre linéaire 2D et 3D (voire 4D). J'essaye d'imiter les possibilités (de base) de GLSL (je sais qu'il y a GLM qui y arrive bien mieux, mais bon...) pour pouvoir étendre la lib par la suite avec des interpolations/splines en tout genre, puis aussi pour m'en servir encore après dans des projets plus spécifiques.
    En fait, actuellement, c'est mon bac-à-sable de méta-programmation, où je teste pas mal de méthodes de génération de code.
    J'ai déjà crée une autre version semblable, mais basée sur le préprocesseur, et franchement, c'est moche question code, illisible même, et ca prend 3 ans à compiler. Maintenant, c'est au compilateur d'être pris au flanc ^^.

    Le but de tout ceci, c'est d'avoir une lib d'algèbre 3D avec le moins de rédondances (sémantiques et syntaxiques) possible, et fonctionnelle directement avec le compilateur (et le préprocesseur), sans avoir à passer par un parseur-générateur de code ou autre préprocesseur externe.

  8. #8
    Membre averti
    Homme Profil pro
    Game Graphics Programmer
    Inscrit en
    Août 2006
    Messages
    408
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Game Graphics Programmer
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2006
    Messages : 408
    Points : 392
    Points
    392
    Par défaut
    J'ai réussi à obtenir ce que je voulais, cf. le code joint.
    Attention, c'est hardcore et ca vous fera sûrement fûmer la tête, vu les moyens détournés dont je me suis servi.

    EDIT: ah oui, j'aimerais avoir vos avis sur le code (qualité, lisibilité, effectivité...).
    Fichiers attachés Fichiers attachés

Discussions similaires

  1. insérer une image dans PHP, c'est possible ?
    Par misshelen dans le forum Langage
    Réponses: 3
    Dernier message: 12/01/2009, 14h40
  2. Probleme d utilisation de template dans le cpp
    Par Math75 dans le forum Langage
    Réponses: 2
    Dernier message: 07/10/2005, 16h26
  3. C'est possible dans une requête SELECT ?
    Par Kokito dans le forum Langage SQL
    Réponses: 7
    Dernier message: 15/04/2005, 16h59
  4. [plugins] Equivalent des Live Templates dans Intellij
    Par rozwel dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 04/02/2005, 06h37
  5. Utilisation de template dans un role de fonctions/procedures
    Par Punky65250 dans le forum XSL/XSLT/XPATH
    Réponses: 14
    Dernier message: 01/09/2004, 10h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo