Je suis un fan des tableaux flexibles en C99, du genre :
struct x_t {
...
Truc trucs[];
};
Or j'ai l'impression que ça n'existe pas en C++ (et je vois aussi de
bonne raisons pour que ça n'existe pas avec le mécanisme
new/constructeur, puisque l'allocateur aurait besoin d'infos qui
arrivent au constructeur). Ma question est : y a-t-il un moyen propre
de contourner cela, à coup de "placement new" ou autre ? Quelqu'un
a-t-il une autre idée ?
Meri d'avance.
-- Alain.
P/S: Deux mots d'explications : j'ai beaucoup (vraiment beaucoup) de
structures du genre de celle ci-dessus, avec des tableaux de petite
taille. Je ne veux pas allouer deux objets (la struct, puis le
tableau) à chaque fois. Les tableaux flexibles me permettent de faire
cela en C. J'aimerais faire la même chose en C++, et j'aimerais m'en
tirer sans avoir à gérer ma propre allocation.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Jean-Marc Bourguet
Alain Ketterlin writes:
Je suis un fan des tableaux flexibles en C99, du genre :
struct x_t { ... Truc trucs[]; };
Or j'ai l'impression que ça n'existe pas en C++ (et je vois aussi de bonne raisons pour que ça n'existe pas avec le mécanisme new/constructeur, puisque l'allocateur aurait besoin d'infos qui arrivent au constructeur). Ma question est : y a-t-il un moyen propre de contourner cela, à coup de "placement new" ou autre ? Quelqu'un a-t-il une autre idée ?
Meri d'avance.
-- Alain.
P/S: Deux mots d'explications : j'ai beaucoup (vraiment beaucoup) de structures du genre de celle ci-dessus, avec des tableaux de petite taille. Je ne veux pas allouer deux objets (la struct, puis le tableau) à chaque fois. Les tableaux flexibles me permettent de faire cela en C. J'aimerais faire la même chose en C++, et j'aimerais m'en tirer sans avoir à gérer ma propre allocation.
Quelque chose comme ca (aux erreurs stupides pres) ?
template <typename Base, typename Elem> class VLA { public: VLA(); Elem get(size_t i) const; void set(size_t i, Elem e); static Base* allocate(size_t sz); protected: ~VLA(); private: // not defined VLA(VLA const&); VLA& operator=(VLA const&); private: size_t sz; };
template <typename Base, typename Elem> Elem VLA<Base, Elem>::get(size_t i) { assert(0 <= i && i < sz); return ((Elem*)(((Base*)this)+1))[i]; }
template <typename Base, typename Elem> void VLA<Base, Elem>::set(size_t i, Elem e) { assert(0 <= i && i < sz); ((Elem*)(((Base*)this)+1))[i] = e; }
template <typename Base, typename Elem> Base* VLA<Base, Elem>::allocate(size_t sz) { unsigned char* mem = (unsigned char*)operator new(sizeof(Base)+n*sizeof(Elem)); Base* result = new(mem)Base; result->sz = sz; Elem* tab = (Elem*)(result+1); for (size_t i = 0; i < sz; ++i) { new(tab+i) Elem; } return result; }
template <typename Base, typename Elem> VLA<Base, Elem>::~VLA() { Elem* tab = ((Elem*)(((Base*)this)+1)); for (size_t i = 0; i < sz; ++i) { (tab+i)->~Elem(); } }
A utiliser
class x : public VLA<x, Truc> { ... };
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
Je suis un fan des tableaux flexibles en C99, du genre :
struct x_t {
...
Truc trucs[];
};
Or j'ai l'impression que ça n'existe pas en C++ (et je vois aussi de
bonne raisons pour que ça n'existe pas avec le mécanisme
new/constructeur, puisque l'allocateur aurait besoin d'infos qui
arrivent au constructeur). Ma question est : y a-t-il un moyen propre
de contourner cela, à coup de "placement new" ou autre ? Quelqu'un
a-t-il une autre idée ?
Meri d'avance.
-- Alain.
P/S: Deux mots d'explications : j'ai beaucoup (vraiment beaucoup) de
structures du genre de celle ci-dessus, avec des tableaux de petite
taille. Je ne veux pas allouer deux objets (la struct, puis le
tableau) à chaque fois. Les tableaux flexibles me permettent de faire
cela en C. J'aimerais faire la même chose en C++, et j'aimerais m'en
tirer sans avoir à gérer ma propre allocation.
Quelque chose comme ca (aux erreurs stupides pres) ?
template <typename Base, typename Elem>
class VLA {
public:
VLA();
Elem get(size_t i) const;
void set(size_t i, Elem e);
static Base* allocate(size_t sz);
protected:
~VLA();
private: // not defined
VLA(VLA const&);
VLA& operator=(VLA const&);
private:
size_t sz;
};
template <typename Base, typename Elem>
Elem VLA<Base, Elem>::get(size_t i)
{
assert(0 <= i && i < sz);
return ((Elem*)(((Base*)this)+1))[i];
}
template <typename Base, typename Elem>
void VLA<Base, Elem>::set(size_t i, Elem e)
{
assert(0 <= i && i < sz);
((Elem*)(((Base*)this)+1))[i] = e;
}
template <typename Base, typename Elem>
Base* VLA<Base, Elem>::allocate(size_t sz)
{
unsigned char* mem = (unsigned char*)operator new(sizeof(Base)+n*sizeof(Elem));
Base* result = new(mem)Base;
result->sz = sz;
Elem* tab = (Elem*)(result+1);
for (size_t i = 0; i < sz; ++i) {
new(tab+i) Elem;
}
return result;
}
template <typename Base, typename Elem>
VLA<Base, Elem>::~VLA()
{
Elem* tab = ((Elem*)(((Base*)this)+1));
for (size_t i = 0; i < sz; ++i) {
(tab+i)->~Elem();
}
}
A utiliser
class x : public VLA<x, Truc>
{
...
};
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Je suis un fan des tableaux flexibles en C99, du genre :
struct x_t { ... Truc trucs[]; };
Or j'ai l'impression que ça n'existe pas en C++ (et je vois aussi de bonne raisons pour que ça n'existe pas avec le mécanisme new/constructeur, puisque l'allocateur aurait besoin d'infos qui arrivent au constructeur). Ma question est : y a-t-il un moyen propre de contourner cela, à coup de "placement new" ou autre ? Quelqu'un a-t-il une autre idée ?
Meri d'avance.
-- Alain.
P/S: Deux mots d'explications : j'ai beaucoup (vraiment beaucoup) de structures du genre de celle ci-dessus, avec des tableaux de petite taille. Je ne veux pas allouer deux objets (la struct, puis le tableau) à chaque fois. Les tableaux flexibles me permettent de faire cela en C. J'aimerais faire la même chose en C++, et j'aimerais m'en tirer sans avoir à gérer ma propre allocation.
Quelque chose comme ca (aux erreurs stupides pres) ?
template <typename Base, typename Elem> class VLA { public: VLA(); Elem get(size_t i) const; void set(size_t i, Elem e); static Base* allocate(size_t sz); protected: ~VLA(); private: // not defined VLA(VLA const&); VLA& operator=(VLA const&); private: size_t sz; };
template <typename Base, typename Elem> Elem VLA<Base, Elem>::get(size_t i) { assert(0 <= i && i < sz); return ((Elem*)(((Base*)this)+1))[i]; }
template <typename Base, typename Elem> void VLA<Base, Elem>::set(size_t i, Elem e) { assert(0 <= i && i < sz); ((Elem*)(((Base*)this)+1))[i] = e; }
template <typename Base, typename Elem> Base* VLA<Base, Elem>::allocate(size_t sz) { unsigned char* mem = (unsigned char*)operator new(sizeof(Base)+n*sizeof(Elem)); Base* result = new(mem)Base; result->sz = sz; Elem* tab = (Elem*)(result+1); for (size_t i = 0; i < sz; ++i) { new(tab+i) Elem; } return result; }
template <typename Base, typename Elem> VLA<Base, Elem>::~VLA() { Elem* tab = ((Elem*)(((Base*)this)+1)); for (size_t i = 0; i < sz; ++i) { (tab+i)->~Elem(); } }
A utiliser
class x : public VLA<x, Truc> { ... };
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
Alain Ketterlin
Jean-Marc Bourguet writes:
Alain Ketterlin writes:
Je suis un fan des tableaux flexibles en C99, du genre :
struct x_t { ... Truc trucs[]; };
Quelque chose comme ca (aux erreurs stupides pres) ?
[...]
template <typename Base, typename Elem> class VLA { public: VLA(); Elem get(size_t i) const; void set(size_t i, Elem e); static Base* allocate(size_t sz); protected: ~VLA(); private: // not defined VLA(VLA const&); VLA& operator=(VLA const&); private: size_t sz; };
[...]
Ouais, c'est à quelque chose de ce gout que je pensais, mais j'avais sous-estimé la sophistication. Merci pour le code, c'est impeccable.
Je suis un fan des tableaux flexibles en C99, du genre :
struct x_t { ... Truc trucs[]; };
Quelque chose comme ca (aux erreurs stupides pres) ?
[...]
template <typename Base, typename Elem> class VLA { public: VLA(); Elem get(size_t i) const; void set(size_t i, Elem e); static Base* allocate(size_t sz); protected: ~VLA(); private: // not defined VLA(VLA const&); VLA& operator=(VLA const&); private: size_t sz; };
[...]
Ouais, c'est à quelque chose de ce gout que je pensais, mais j'avais sous-estimé la sophistication. Merci pour le code, c'est impeccable.
-- Alain.
Jean-Marc Bourguet
Alain Ketterlin writes:
Jean-Marc Bourguet writes:
> Alain Ketterlin writes: > >> Je suis un fan des tableaux flexibles en C99, du genre : >> >> struct x_t { >> ... >> Truc trucs[]; >> }; > Quelque chose comme ca (aux erreurs stupides pres) ? [...] > template <typename Base, typename Elem> > class VLA { > public: > VLA(); > Elem get(size_t i) const; > void set(size_t i, Elem e); > static Base* allocate(size_t sz); > protected: > ~VLA(); > private: // not defined > VLA(VLA const&); > VLA& operator=(VLA const&); > private: > size_t sz; > }; [...]
Ouais, c'est à quelque chose de ce gout que je pensais, mais j'avais sous-estimé la sophistication. Merci pour le code, c'est impeccable.
Il doit y avoir moyen de faire mieux. Au moins - en mettant l'initialisation du tableau avant l'appel au constructeur de Base (ca correspond mieux au fait que les Elem sont detruits dans le destructeur de VLA) - en mettant le constructeur de VLA protected. - une piste a explorer: un new avec placement plutot que VLA<>::allocate (le parametre de placement, c'est la taille du VLA), ca permettrait d'utiliser tous les constructeur de Base qu'on desire.
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
> Alain Ketterlin <alain@dpt-info.u-strasbg.fr> writes:
>
>> Je suis un fan des tableaux flexibles en C99, du genre :
>>
>> struct x_t {
>> ...
>> Truc trucs[];
>> };
> Quelque chose comme ca (aux erreurs stupides pres) ?
[...]
> template <typename Base, typename Elem>
> class VLA {
> public:
> VLA();
> Elem get(size_t i) const;
> void set(size_t i, Elem e);
> static Base* allocate(size_t sz);
> protected:
> ~VLA();
> private: // not defined
> VLA(VLA const&);
> VLA& operator=(VLA const&);
> private:
> size_t sz;
> };
[...]
Ouais, c'est à quelque chose de ce gout que je pensais, mais j'avais
sous-estimé la sophistication. Merci pour le code, c'est impeccable.
Il doit y avoir moyen de faire mieux. Au moins
- en mettant l'initialisation du tableau avant l'appel au constructeur de
Base (ca correspond mieux au fait que les Elem sont detruits dans le
destructeur de VLA)
- en mettant le constructeur de VLA protected.
- une piste a explorer: un new avec placement plutot que VLA<>::allocate
(le parametre de placement, c'est la taille du VLA), ca permettrait
d'utiliser tous les constructeur de Base qu'on desire.
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
> Alain Ketterlin writes: > >> Je suis un fan des tableaux flexibles en C99, du genre : >> >> struct x_t { >> ... >> Truc trucs[]; >> }; > Quelque chose comme ca (aux erreurs stupides pres) ? [...] > template <typename Base, typename Elem> > class VLA { > public: > VLA(); > Elem get(size_t i) const; > void set(size_t i, Elem e); > static Base* allocate(size_t sz); > protected: > ~VLA(); > private: // not defined > VLA(VLA const&); > VLA& operator=(VLA const&); > private: > size_t sz; > }; [...]
Ouais, c'est à quelque chose de ce gout que je pensais, mais j'avais sous-estimé la sophistication. Merci pour le code, c'est impeccable.
Il doit y avoir moyen de faire mieux. Au moins - en mettant l'initialisation du tableau avant l'appel au constructeur de Base (ca correspond mieux au fait que les Elem sont detruits dans le destructeur de VLA) - en mettant le constructeur de VLA protected. - une piste a explorer: un new avec placement plutot que VLA<>::allocate (le parametre de placement, c'est la taille du VLA), ca permettrait d'utiliser tous les constructeur de Base qu'on desire.
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
xylo
Le Fri, 07 Nov 2008 08:47:50 +0100, Jean-Marc Bourguet a écrit:
Alain Ketterlin writes:
Jean-Marc Bourguet writes:
> Alain Ketterlin writes: > >> Je suis un fan des tableaux flexibles en C99, du genre : >> >> struct x_t { >> ... >> Truc trucs[]; >> }; > Quelque chose comme ca (aux erreurs stupides pres) ? [...] > template <typename Base, typename Elem> > class VLA { > public: > VLA(); > Elem get(size_t i) const; > void set(size_t i, Elem e); > static Base* allocate(size_t sz); > protected: > ~VLA(); > private: // not defined > VLA(VLA const&); > VLA& operator=(VLA const&); > private: > size_t sz; > }; [...]
Ouais, c'est à quelque chose de ce gout que je pensais, mais j'avais sous-estimé la sophistication. Merci pour le code, c'est impeccable.
Il doit y avoir moyen de faire mieux. Au moins - en mettant l'initialisation du tableau avant l'appel au constructeur de Base (ca correspond mieux au fait que les Elem sont detruits dans le destructeur de VLA) - en mettant le constructeur de VLA protected. - une piste a explorer: un new avec placement plutot que VLA<>::allocate (le parametre de placement, c'est la taille du VLA), ca permettrait d'utiliser tous les constructeur de Base qu'on desire.
A+
VLA : very large array ?
-- Apply rot13 to this e-mail address before using it. JM Marino http://jm.marino.free.fr
Le Fri, 07 Nov 2008 08:47:50 +0100, Jean-Marc Bourguet a écrit:
> Alain Ketterlin <alain@dpt-info.u-strasbg.fr> writes:
>
>> Je suis un fan des tableaux flexibles en C99, du genre :
>>
>> struct x_t {
>> ...
>> Truc trucs[];
>> };
> Quelque chose comme ca (aux erreurs stupides pres) ?
[...]
> template <typename Base, typename Elem>
> class VLA {
> public:
> VLA();
> Elem get(size_t i) const;
> void set(size_t i, Elem e);
> static Base* allocate(size_t sz);
> protected:
> ~VLA();
> private: // not defined
> VLA(VLA const&);
> VLA& operator=(VLA const&);
> private:
> size_t sz;
> };
[...]
Ouais, c'est à quelque chose de ce gout que je pensais, mais j'avais
sous-estimé la sophistication. Merci pour le code, c'est impeccable.
Il doit y avoir moyen de faire mieux. Au moins
- en mettant l'initialisation du tableau avant l'appel au constructeur de
Base (ca correspond mieux au fait que les Elem sont detruits dans le
destructeur de VLA)
- en mettant le constructeur de VLA protected.
- une piste a explorer: un new avec placement plutot que VLA<>::allocate
(le parametre de placement, c'est la taille du VLA), ca permettrait
d'utiliser tous les constructeur de Base qu'on desire.
A+
VLA : very large array ?
--
Apply rot13 to this e-mail address before using it.
JM Marino
http://jm.marino.free.fr
Le Fri, 07 Nov 2008 08:47:50 +0100, Jean-Marc Bourguet a écrit:
Alain Ketterlin writes:
Jean-Marc Bourguet writes:
> Alain Ketterlin writes: > >> Je suis un fan des tableaux flexibles en C99, du genre : >> >> struct x_t { >> ... >> Truc trucs[]; >> }; > Quelque chose comme ca (aux erreurs stupides pres) ? [...] > template <typename Base, typename Elem> > class VLA { > public: > VLA(); > Elem get(size_t i) const; > void set(size_t i, Elem e); > static Base* allocate(size_t sz); > protected: > ~VLA(); > private: // not defined > VLA(VLA const&); > VLA& operator=(VLA const&); > private: > size_t sz; > }; [...]
Ouais, c'est à quelque chose de ce gout que je pensais, mais j'avais sous-estimé la sophistication. Merci pour le code, c'est impeccable.
Il doit y avoir moyen de faire mieux. Au moins - en mettant l'initialisation du tableau avant l'appel au constructeur de Base (ca correspond mieux au fait que les Elem sont detruits dans le destructeur de VLA) - en mettant le constructeur de VLA protected. - une piste a explorer: un new avec placement plutot que VLA<>::allocate (le parametre de placement, c'est la taille du VLA), ca permettrait d'utiliser tous les constructeur de Base qu'on desire.
A+
VLA : very large array ?
-- Apply rot13 to this e-mail address before using it. JM Marino http://jm.marino.free.fr
Alain Ketterlin
xylo writes:
VLA : very large array ?
Pourquoi pas. Mais je pense que là c'était pour "variable length array".
-- Alain.
xylo <chovp.wzz@serr.se> writes:
VLA : very large array ?
Pourquoi pas. Mais je pense que là c'était pour "variable length
array".