Yopla, je rencontre un petit soucis de compréhension avec C++
Je code pour la R15 et plus.
Si je crée une class template avec un typename et que je l'assigne à une variable en utilisant la fonction newObj cela fonctionne. (du moins j'ai pas de message d'insultes)
Si j'essayes d'avoir deux typename j'ai des messages différents suivant le nombre de parenthèses que je mets ...
ça vas de
"parse issue expected >" + "parse issue type name requires a specifier or qualifier"
à
"parse issue expected expression"
une version ultra simplifié qui reproduit le problème.
Code:template <typename T, typename T2> class myclass { public: T toto; T2 tata; myclass(); ~myclass(); }; template <typename T, typename T2> myclass<T, T2>::myclass() { } template <typename T, typename T2> myclass<T, T2>::~myclass() { } //puis dans une fonction (draw, execute, getVirtualObject on s'en fout) DRAWRESULT ObjectSlider::Draw(BaseObject *op, DRAWPASS drawpass, BaseDraw *bd, BaseDrawHelp *bh) { // ......... des trucs et des bidules myclass<Int32, Vector>* tata = NewObj(myclass<Int32, Vector>); // génère le message d'erreur complet myclass<Int32, Vector>* toto = NewObj((myclass<Int32, Vector>)); // génère le message d'erreur plus simple myclass<Int32, Vector>* titi = new (myclass<Int32, Vector>); // compile sans problème. // ... des trucs et des machins DeleteObj(tata); //et autre suppression d'objet. return SUPER::Draw(op, drawpass, bd, bh); }
je comprends pas pourquoi ça ne fonctionne pas avec deux paramètres. SI quelqu'un a une idée, je prends T.T
J'vais peut être poster sur plugincafé mais si quelqu'un a une idée merci d'avance
en même temps je sais pas si j'ai besoin d'un pointeur mais c'est juste pour comprendre xD
Dernière modification par valkaari ; 09/03/2016 à 20h31.
Je t'aurais bien aidé, mais je ne sais pas ce qu'est un template, ni ne comprends le ~ devant myclass(), ni à quoi servent les chevrons ici. : o
Salut,
C'est parce que NewObj est une macro :
Et quand tu écris NewObj(myclass<Int32, Vector>), je pense que la macro NewObj prend "myclass<Int32" pour 'T' et "Vector>" pour les varargs à cause de la virgule.Code PHP:
#define NewObj(T, ...) MAXON_SAFE_PLACEMENT_NEW(maxon::DefaultAllocator::Alloc(SIZEOF(T), C4D_MISC_ALLOC_LOCATION)) T(__VA_ARGS__)
Parait-il que ça, ça fonctionne, mais pas chez moi:
Sinon, tu peux faire un truc pas très joli comme ça, mais y'a surement mieux :Code PHP:
#define COMMA ,
NewObj(myclass<Int32 COMMA Vector>)
Code PHP:
static myclass<Int32, Vector>* NewToto()
{
return MAXON_SAFE_PLACEMENT_NEW(maxon::DefaultAllocator::Alloc((maxon::Int)sizeof(myclass<Int32, Vector>), C4D_MISC_ALLOC_LOCATION)) myclass<Int32, Vector>();
}
myclass<Int32, Vector>* toto = NewToto();
merci d'avoir pris le temps de regarder
Il y a surement une définition plus précise mais en gros un template te permet de définir un objet/class/function sans en connaitre le type.
L'exemple bateau c'est d'écrire une fonction addition. Si tu utilises un template, tu peux utiliser la fonction pour des int, des float et même des strings. Puis tu peux aussi spécialiser.
J'suis en train de coder un octree et j'utilises les templates pour pouvoir y stocker n'importe quoi comme données. Je peux vouloir y stocker des indices de points, des vectors, des CPolygons, ce que je veux en gros. C'est pour ça que je voulais utiliser des Int32 (indices de points) et des Vector (qui détermine la position dans l'octree).
Et en utilisant un max le SDK de cinema4D pour être le plus "maison" possible. Mais j'suis tombé sur ce petit "bug"
Sinon le ~ c'est pour le destructeur de la class, je voulais juste mettre un constructeur et un destructeur pour dire que je fais rien de spécial dedans. J'imagines que les concepteurs voulait dire que le destructeur c'est l'inverse (~) du constructeur
Sinon pour mon problème oui j'ai vu la macro aussi, l'alloc, le sizeof.
Pour un typename ça fonctionne avec les arguments mais pas avec plusieurs. Et oui le coup de la fonction ça marche, on peut le faire directement aussi (normal) en gagnant un peu de code tapé avec auto. Mais bon spa propre
bon c'est clairement SIZEOF(x) qui m'emmerde là.... : /Code:auto* toto = MAXON_SAFE_PLACEMENT_NEW(maxon::DefaultAllocator::Alloc((maxon::Int)sizeof(myclass<Int32, Vector>), C4D_MISC_ALLOC_LOCATION)) myclass<Int32, Vector>();
Si je fais juste un Int taille = SIZEOF(myclass<Int32, Vector>); il me dit que je donne trop d'argument pour une "function-like macro incovation"
la dernière fois où j'ai fais des invocations c'était dans final fantasy T.T
Quelle est l'avantage des templates vis a vis de faire une surcharge de classe / fonction? car au moins sa permet de faire des contrôles non? ^^'
SDK Specialist
MAXON Computer GmbH
C'est juste un outil en plus. Le cas classique c'est d'imaginer un contenant. Un coffre, une bouteille, une boite. Peut importe ce qu'il y a dedans.
Si tu dois faire un tableau par exemple, tu sais que tu dois pouvoir ajouter un élément, en supprimer, accéder aux éléments. Le type de données n'est pas important. (Et si c'est le cas tu peux toujours définir certaines spécialisation ou avoir des fonctions callback)
C'est exactement ce que font/sont les stl (ou les BaseArray dans le SDK c4d)
Dans ces cas quand tu veux un nouveau tableau tu dois en définir le type maxon::BaseArray<Int32> monTableau;
C'est la même syntaxe que j'ai plus haut myclass<Int32, Vector>* tata;
Bon j'ai posté sur le forum plugincafé on verra bien s'ils considèrent ça comme un bug ou pas ...
Au final ça à l'air de fonctionner ça :
ou plus simple :Code PHP:
#ifdef SIZEOF
#undef SIZEOF
#endif
#define SIZEOF(x...) ((maxon::Int)sizeof(x))
#define COMMA ,
myclass<Int32, Vector>* tata = NewObj(myclass<Int32 COMMA Vector>);
Code PHP:
#define SINGLE_ARG(...) __VA_ARGS__
...
myclass<Int32, Vector>* tata = NewObj(SINGLE_ARG(myclass<Int32, Vector>));
Dernière modification par xs_yann ; 10/03/2016 à 11h44.
pour la deuxième solution on est obligé de garder la nouvelle macro SIZEOF ?
sur plugincafé il y a NiklasR (un autre bourrin comme yann) qui propose une solution très proche.
Code:template<typename T> struct get_first_param; template<typename R, typename P1> struct get_first_param<R(P1)> { typedef P1 type; }; #define Identity(...) get_first_param<void(__VA_ARGS__)>::type // Then to use NewObj(): myclass<Int32, Vector>* obj = NewObj(Identity(myclass<Int32, Vector>));
Du coup deux solutions, faut que je test les deux pour voir si ça me pose problème pour la suite de mon code ^^
Je peux poster ta solution yann sur le forum plugincafé ? (ou si tu veux le faire toi même)
J'ai répondu.
(Niklas est beaucoup plus bourrin que moi, et plus jeune en plus)
Merci pour les précisions !