 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Michael Guest
|
Posted: Tue Jul 18, 2006 1:57 am Post subject: Comment rendre une classe "iterable"? |
|
|
Bonsoir à tous,
j'ai les deux classes suivantes:
class VideoDevice
{
private:
std::string name;
public:
std::string & GetName() const { return name; }
};
class VideoDeviceEnumerator
{
public:
void FillList(TBox * box);
void getVideoDevice(const std::string & fooName, VideoDevice * vd);
};
Les deux fonctions de VideoDeviceEnumerator énumèrent en interne tous les
périphériques de capture vidéo disponibles sur le système... Et la fonction
FillList est tout ce qu'il y a de restrictif puisqu'elle ne fonctionne
qu'avec les objets de la VCL de Borland.
Je voudrais donc rendre cette classe identique à un itérateur, pour que
l'utilisateur puisse faire comme avec les conteneurs de la STL...
Un truc du genre:
VideoDeviceEnumerator vdEnum;
for (VideoDeviceEnumerator::constIterator ite = vdEnum.begin(); ite !=
vdEnum.end(); ++ite)
box->AddItem(ite->GetName());
Et pour obtenir un VideoDevice:
VideoDeviceEnumerator vdEnum;
VideoDeviceEnumerator::constIterator ite = std::find_if(vdEnum.begin
(),vdEnum.end(),"nom du périphérique");
Enfin, vous voyez de quoi je parle ;)
Comment je peux faire ça?
J'ai entendu dire que c'était pas conseillé de dériver des classes de la
STL, donc j'ai bien peur de devoir réimplémenter tout ça :(
Merci d'avance...
Mike |
|
| Back to top |
|
 |
Pierre Barbier de Reuille Guest
|
Posted: Tue Jul 18, 2006 2:25 am Post subject: Re: Comment rendre une classe "iterable"? |
|
|
Michael wrote:
| Quote: | Bonsoir à tous,
j'ai les deux classes suivantes:
class VideoDevice
{
private:
std::string name;
public:
std::string & GetName() const { return name; }
};
class VideoDeviceEnumerator
{
public:
void FillList(TBox * box);
void getVideoDevice(const std::string & fooName, VideoDevice * vd);
};
Les deux fonctions de VideoDeviceEnumerator énumèrent en interne tous les
périphériques de capture vidéo disponibles sur le système... Et la fonction
FillList est tout ce qu'il y a de restrictif puisqu'elle ne fonctionne
qu'avec les objets de la VCL de Borland.
Je voudrais donc rendre cette classe identique à un itérateur, pour que
l'utilisateur puisse faire comme avec les conteneurs de la STL...
Un truc du genre:
VideoDeviceEnumerator vdEnum;
for (VideoDeviceEnumerator::constIterator ite = vdEnum.begin(); ite !=
vdEnum.end(); ++ite)
box->AddItem(ite->GetName());
Et pour obtenir un VideoDevice:
VideoDeviceEnumerator vdEnum;
VideoDeviceEnumerator::constIterator ite = std::find_if(vdEnum.begin
(),vdEnum.end(),"nom du périphérique");
Enfin, vous voyez de quoi je parle ;)
Comment je peux faire ça?
J'ai entendu dire que c'était pas conseillé de dériver des classes de la
STL, donc j'ai bien peur de devoir réimplémenter tout ça :(
Merci d'avance...
Mike
|
Bien, avec ce que tu donnes comme information y a pas grand chose à dire
sauf que ce que tu as deux solutions (AMA):
1 - le plus simple c'est tu remplis un container de la STL genre un
vector et ensuite "begin" et "end" renvoient simplement le "begin" et
"end" sur ce vecteur. Dans ton type il suffit de mettre dans la
définition de VideoDeviceEnumerator:
typedef vector<VideoDevice>::const_iterator const_iterator;
et le tour est joué ! Ensuite, si ça fait sens, tu peux rajouter
l'itérateur non-constant.
2 - plus compliqué, il faut que tu te fasse une classe qui se comporte
comme un itérateur (à toi de voir quel type d'itérateur, le plus simple
étant le "forward", cf
http://www.sgi.com/tech/stl/ForwardIterator.html). Disons que tu
appelles ta classe "VideoIterator" alors tu mets dans ta classe
VideoDeviceEnumerator:
typdef VideoIterator const_iterator;
puis tu définis begin et end pour renvoyer le bon VideoIterator.
Voilà, j'espère que ça aide, sinon faudrait donner plus d'info sur le
fonctionnement de VideoDeviceEnumerator.
Pierre |
|
| Back to top |
|
 |
Manuel Zaccaria Guest
|
Posted: Tue Jul 18, 2006 3:56 am Post subject: Re: Comment rendre une classe "iterable"? |
|
|
Michael a écrit:
Bonsoir,
| Quote: | j'ai les deux classes suivantes:
class VideoDevice
{
private:
std::string name;
public:
std::string & GetName() const { return name; }
|
std::string const& GetName() const { return name; } // const is const
Si cette classe est une classe de base il est vivement conseillé de définir
un destructeur, soit virtuel et public(*), soit non virtuel et protégé(**).
De plus, comme son nom le fait penser, cette classe gère une ressource.
Dans ce cas mieux vaut désactiver le constructeur de copie et l'opérateur
d'affectation. En résumé :
class VideoDevice
{
private:
std::string name;
// no copy (sans implementation)
VideoDevice(VideoDevice const&);
VideoDevice& operator=(VideoDevice const&);
protected:
// ~VideoDevice() { /* ... */ } // (*) interdire la destruction par la base
public:
// virtual ~VideoDevice() { /* ... */ } // (**) autoriser (décommenter
selon)
std::string const& GetName() const { return name; }
};
| Quote: |
class VideoDeviceEnumerator
{
public:
void FillList(TBox * box);
void getVideoDevice(const std::string & fooName, VideoDevice * vd);
};
Les deux fonctions de VideoDeviceEnumerator énumèrent en interne tous les
périphériques de capture vidéo disponibles sur le système... Et la
fonction
FillList est tout ce qu'il y a de restrictif puisqu'elle ne fonctionne
qu'avec les objets de la VCL de Borland.
|
Où sont les données membres ? On peut pas deviner comme ça si tout est
rangé dans un std::map<std::string, VideoDevice*> ou autre.
Disons que c'est un map pour simplifier.
| Quote: | Je voudrais donc rendre cette classe identique à un itérateur, pour que
l'utilisateur puisse faire comme avec les conteneurs de la STL...
Un truc du genre:
|
class VideoDeviceEnumerator
{
private:
// map de VideoDevice* si polymorphe
typedef std::map<std::string, VideoDevice*> map_type;
map_type devices;
public:
class const_iterator
{
private:
map_type::const_iterator iter;
public:
const_iterator(map_type::const_iterator iter):iter(iter){}
const_iterator& operator++() { ++iter; return *this; }
VideoDevice const* operator->() const { return iter->second; }
VideoDevice const& operator*() const { return *iter->second; }
};
const_iterator begin() { return devices.begin(); }
const_iterator end() { return devices.end(); }
// éventuellement, pour consulter/modifier ou remplir le map
VideoDevice* operator[](std::string const& name) { return
devices[name]; }
// etc...
};
// ...
VideoDeviceEnumerator vdEnum;
VideoDeviceEnumerator::const_iterator ite = vdEnum.begin();
VideoDeviceEnumerator::const_iterator end = vdEnum.end();
for(;ite != end; ++ite)
box->AddItem(ite->GetName());
| Quote: |
Et pour obtenir un VideoDevice:
|
VideoDeviceEnumerator vdEnum;
VideoDeviceEnumerator::const_iterator ite = vdEnum.begin();
VideoDeviceEnumerator::const_iterator end = vdEnum.end();
VideoDeviceEnumerator::const_iterator ite = std::find(ite, end, "nom du
périphérique");
ou
VideoDevice* device = vdEnum["nom du périphérique"];
| Quote: |
Comment je peux faire ça?
|
C'est une solution mais je n'ai pas testé le code (ça devrait tourner).
| Quote: |
J'ai entendu dire que c'était pas conseillé de dériver des classes de la
STL, ...
|
Tout juste.
Manuel |
|
| Back to top |
|
 |
Manuel Zaccaria Guest
|
Posted: Tue Jul 18, 2006 4:13 am Post subject: Re: Comment rendre une classe "iterable"? |
|
|
J'aime pas trop me reprendre mais j'ai écrit :
| Quote: | Si cette classe est une classe de base il est vivement conseillé de
définir
un destructeur, soit virtuel et public(*), soit non virtuel et
protégé(**).
...
|
alors que
| Quote: | protected:
// ~VideoDevice() { /* ... */ } // (*) interdire la destruction par la
base
public:
// virtual ~VideoDevice() { /* ... */ } // (**) autoriser (décommenter
selon)
|
(*) <=> (**), à l'envers
[...]
| Quote: | VideoDeviceEnumerator::const_iterator ite = std::find(ite, end, "nom du
périphérique");
|
Impossible comme ça! il faut find_if avec un prédicat.
Bref, y'a sûrement d'autres erreurs... 'suis fatigué.
Manuel |
|
| Back to top |
|
 |
Stephane Wirtel Guest
|
Posted: Tue Jul 18, 2006 9:12 am Post subject: Re: Comment rendre une classe "iterable"? |
|
|
| Quote: | Bref, y'a sûrement d'autres erreurs... 'suis fatigué.
Peut-être fatigué, mais ça faisait un bout de temps que je me posais une question |
concernant l'implémentation d'une surcouche iterator au dessus
des composants VCL de Borland.
Dans mon cas, j'ai besoin d'un iterator pour TList et TSQLQuery.
Le problème avec TList c'est qu'il s'agit un tableau qui contient des pointeurs
de type 'void', ce qui permet d'avoir une compatibilité avec Delphi.
Ce que je fais assez fréquemment, je travaille avec des STL containers et
quand il est nécessaire des passer des VCL "containers", je le génère
automatiquement.
Merci de cette info
Stef |
|
| Back to top |
|
 |
Michael Guest
|
Posted: Tue Jul 18, 2006 11:47 pm Post subject: Re: Comment rendre une classe "iterable"? |
|
|
| Quote: | Si cette classe est une classe de base il est vivement conseillé de
définir un destructeur, soit virtuel et public(*), soit non virtuel et
protégé(**). De plus, comme son nom le fait penser, cette classe gère
une ressource. Dans ce cas mieux vaut désactiver le constructeur de
copie et l'opérateur d'affectation. En résumé :
|
Pas de soucis pour tout ça, j'ai fait court pour l'exemple...
| Quote: | Où sont les données membres ? On peut pas deviner comme ça si tout est
rangé dans un std::map<std::string, VideoDevice*> ou autre.
Disons que c'est un map pour simplifier.
|
Il n'y a pas de map
Par exemple, le code de GetVideoDevice
HRESULT FilterEnumerator::GetFilter(const AnsiString & filterName,
FilterBase * pComp) {
if (!pEm)
return E_POINTER;
pEm->Reset();
unsigned long cFetched = 0;
CComPtr<IMoniker> pMoniker;
while(SUCCEEDED(pEm->Next(1, &pMoniker, &cFetched)) && pMoniker)
{
CComPtr<IPropertyBag> pPropBag;
HRESULT hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void
**)&pPropBag); if (FAILED(hr))
return hr;
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (FAILED(hr))
return hr;
AnsiString name = varName.bstrVal;
if (name == filterName)
{
CComPtr<IBaseFilter> pFilter;
hr = pMoniker->BindToObject(0, 0,
IID_IBaseFilter,(void**)&pFilter); if (FAILED(hr))
return hr;
pComp->SetFilter(pFilter,name);
return S_OK;
}
pMoniker.Release();
}
return E_FAIL;
}
Et là celui de la classe:
class FilterEnumerator
{
protected:
CComPtr<ICreateDevEnum> pSysDevEnum;
CComPtr<IEnumMoniker> pEm;
public:
FilterEnumerator();
//virtual ~DeviceEnumerator();
void Enumerate(TCustomListBox * box, const AnsiString & filterName
= ""); bool FilterExists(const AnsiString & filterName) const;
HRESULT GetFilter(const AnsiString & filterName, FilterBase *
pComp); bool IsFilterInCateg() const;
};
Ce qu'il faut faire je pense, c'est intégrer cette ligne dans la détection
du .end() et de l'opérateur ++
while(SUCCEEDED(pEm->Next(1, &pMoniker, &cFetched)) && pMoniker)
Je vais essayer de me débrouiller, on verra bien...
J'espérer pouvoir me débrouiller avec la STL... |
|
| Back to top |
|
 |
Manuel Zaccaria Guest
|
Posted: Sat Jul 22, 2006 9:38 pm Post subject: Re: Comment rendre une classe "iterable"? |
|
|
Michael a écrit:
| Quote: | Disons que c'est un map pour simplifier.
Il n'y a pas de map
Par exemple, le code de GetVideoDevice
|
[snip code]
| Quote: | Ce qu'il faut faire je pense, c'est intégrer cette ligne dans la détection
du .end() et de l'opérateur ++
while(SUCCEEDED(pEm->Next(1, &pMoniker, &cFetched)) && pMoniker)
|
Presque ça. Je ne suis pas d'accord pour .end() par contre.
| Quote: |
Je vais essayer de me débrouiller, on verra bien...
J'espérer pouvoir me débrouiller avec la STL...
|
Pardon si c'est trop H.S.
Le sujet est spécifique COM/Win32 mais je répond car le but est de
créer une façade (adaptateur) vers la STL.
La fonction GetVideoDevice fait trop de travail pour en faire un iterateur.
Il vaut mieux séparer l'itération de l'extraction des attributs.
Je ferais un iterateur sur les monikers (réutilisable du coup) et quelques
fonctions libres et enfin une classe exception :
/////////////////////////////////////
// la classe exception pour COM
// ou bien une autre... peu importe.
class com_exception : public exception
{
private:
HRESULT hr;
public:
com_exception(HRESULT hr):hr(hr){}
HRESULT result() const { return hr; }
};
/////////////////////////////////////
// la classe iterateur de monikers
class moniker_iterator
{
private:
CComPtr<IEnumMoniker> pEm;
CComPtr<IMoniker> pMoniker;
public:
moniker_iterator(CComPtr<IEnumMoniker> const& pem) // begin
: pEm(pem) {
if(pEm) {
HRESULT hr = pem->Reset(&pEm);
if(FAILED(hr))
throw com_exception(hr);
operator++(); // premier élément
}
}
moniker_iterator(moniker_iterator const& it) { // copie
if(it.pEm) {
HRESULT hr = it.pEm->Clone(&pEm);
if(FAILED(hr))
throw com_exception(hr);
}
}
moniker_iterator() {} // end
~moniker_iterator(){}
bool operator!=() const { return !operator==(it); }
bool operator==(moniker_iterator const& it) const {
return pMoniker == it.pMoniker;
}
moniker_iterator& operator++() {
if(!pEM)
throw com_exception(E_POINTER);
unsigned long cFetched;
IMoniker* pNewMoniker;
HRESULT hr = pEm->Next(1, &pNewMoniker, &cFetched);
// Tout va bien! mise à jour et retour.
pMoniker = SUCCEEDED(hr) ? pNewMoniker : 0;
return *this;
}
IMoniker* operator->() {
if(!pEM || !pMoniker)
throw com_exception(E_POINTER);
return pMoniker;
}
IMoniker& operator*() {
if(!pEM || !pMoniker)
throw com_exception(E_POINTER);
return *pMoniker;
}
};
/////////////////////////////////////
// les fonctions libres
AnsiString FriendlyName(IMoniker& moniker)
{
CComPtr<IPropertyBag> pPropBag;
CComVariant varName;
HRESULT hr;
if(FAILED(hr = moniker.BindToStorage(0, 0, IID_IPropertyBag,
(void**)&pPropBag))
|| FAILED(hr = pPropBag->Read(L"FriendlyName", &varName, 0)))
throw com_exception(hr);
return varName.bstrVal;
}
void BindToFilter(IMoniker& moniker, FilterBase& comp, AnsiString const&
name)
{
CComPtr<IBaseFilter> pFilter;
HRESULT hr = moniker.BindToObject(0, 0,
IID_IBaseFilter,(void**)&pFilter);
if (FAILED(hr))
throw com_exception(hr);
comp.SetFilter(pFilter, name);
}
etc...
/////////////////////////////////////
// exemple
AnsiString filterName = "MyFilter";
moniker_iterator begin(pem), end;
while((begin != end) && (FriendlyName(*begin) != filterName))
++begin;
if(begin != end)
BindToFilter(*begin, comp[i++], filterName);
/////////////////////////////////////
Normalement je compile et j'enlève les bugs... c'est pas testé donc.
Manuel |
|
| Back to top |
|
 |
Sylvain Guest
|
Posted: Sun Jul 23, 2006 1:05 am Post subject: Exception [was: Re: Comment rendre une classe "iterable"?] |
|
|
Manuel Zaccaria wrote on 22/07/2006 18:38:
| Quote: |
class moniker_iterator {
public:
moniker_iterator(CComPtr<IEnumMoniker> const& pem) .. {
...
throw com_exception(hr);
...
}
moniker_iterator(moniker_iterator const& it){
...
throw com_exception(hr);
}
|
est-ce les évolutions en cours de la norme prévoir d'obligeation de
déclaration des exceptions lévées (localement ou héritées) par une méthode ?
ie:
moniker_iterator(moniker_iterator const& it)
throw (com_exception)
{
...
}
est-ce que cela pourra s'accompagner d'une obligeation de catch de la
part du code appelant (s'il ne redéclare pas les mêmes throw) ?
Sylvain. |
|
| Back to top |
|
 |
Manuel Zaccaria Guest
|
Posted: Sun Jul 23, 2006 2:35 am Post subject: Re: Exception [was: Re: Comment rendre une classe "iterable" |
|
|
Sylvain a écrit:
| Quote: | est-ce les évolutions en cours de la norme prévoir d'obligeation de
déclaration des exceptions lévées (localement ou héritées) par une méthode
?
ie:
moniker_iterator(moniker_iterator const& it)
throw (com_exception)
{
...
}
est-ce que cela pourra s'accompagner d'une obligeation de catch de la part
du code appelant (s'il ne redéclare pas les mêmes throw) ?
|
Des spécifications d'exception comme en java ? J'espère bien que non.
Herb Sutter résume bien bien la situation :
"A Pragmatic Look at Exception Specifications"
http://www.gotw.ca/publications/mill22.htm
La morale est : "même pas throw()" ...discussion ?
Manuel |
|
| Back to top |
|
 |
Sylvain Guest
|
Posted: Sun Jul 23, 2006 2:55 am Post subject: Re: Exception [was: Re: Comment rendre une classe "iterable" |
|
|
Manuel Zaccaria wrote on 22/07/2006 23:35:
| Quote: |
Des spécifications d'exception comme en java ? J'espère bien que non.
Herb Sutter résume bien bien la situation :
|
les 2 points sont liés ? Java fait une vérification à la compil.,
l'article ne parle que de vérification au runtime.
ma question portait sur un contrôle à la compilation.
Sylvain. |
|
| Back to top |
|
 |
Manuel Zaccaria Guest
|
Posted: Sun Jul 23, 2006 3:03 am Post subject: Re: Exception [was: Re: Comment rendre une classe "iterable" |
|
|
Sylvain a écrit:
| Quote: | Des spécifications d'exception comme en java ? J'espère bien que non.
Herb Sutter résume bien bien la situation :
les 2 points sont liés ? Java fait une vérification à la compil.,
l'article ne parle que de vérification au runtime.
ma question portait sur un contrôle à la compilation.
|
Si je me souviens bien, le fait de mettre des specifications
d'exception _force_ le compilateur a insérer des vérifications au
runtime (ce qui conduit à un abort() inconditionel si on les viole).
Manuel |
|
| Back to top |
|
 |
Loïc Joly Guest
|
Posted: Sun Jul 23, 2006 3:07 am Post subject: Re: Exception [was: Re: Comment rendre une classe "iterable" |
|
|
Sylvain a écrit :
| Quote: | Manuel Zaccaria wrote on 22/07/2006 23:35:
Des spécifications d'exception comme en java ? J'espère bien que non.
Herb Sutter résume bien bien la situation :
les 2 points sont liés ? Java fait une vérification à la compil.,
l'article ne parle que de vérification au runtime.
ma question portait sur un contrôle à la compilation.
|
Pour faire ça, il faut à la compilation fournir au compilateur les
données nécessaires pour valider qu'une fonction en cours ne risque pas
d'émettre d'autres exceptions que celle qu'il a déclarées.
Fournir ces données, c'est au choix :
- faire la croix sur tout le code existant, puisque ça veut dire imposer
d'écrire les spécifications d'exception sur chaque déclaration de fonction.
- faire une croix sur la compilation séparée (et donc les biblithèques
livrées sans code source).
Je ne pense pas qu'aucun de ces choix soit acceptable en C++. D'où la
vérification au run-time.
--
Loïc |
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Sun Jul 23, 2006 5:13 am Post subject: Re: Exception [was: Re: Comment rendre une classe "iterable" |
|
|
Sylvain wrote:
| Quote: | Manuel Zaccaria wrote on 22/07/2006 23:35:
Des spécifications d'exception comme en java ? J'espère bien
que non.
Herb Sutter résume bien bien la situation :
les 2 points sont liés ? Java fait une vérification à la
compil.,
|
Ce n'est pas tout à fait vrai. Le Java fait une vérification à
la compile pour certaines exceptions, et pas pour d'autres. Et
c'est impossible en Java d'écrire une garantie qu'une fonction
ne sortira pas par une exception, qui est la seule garantie
réelement utile. (Et ça ne me déplairait pas qu'elle soit
enforcée par le compilateur en C++, mais ça ne va pas se faire.)
--
James Kanze kanze.james (AT) neuf (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Sun Jul 23, 2006 5:15 am Post subject: Re: Exception [was: Re: Comment rendre une classe "iterable" |
|
|
Manuel Zaccaria wrote:
| Quote: | Sylvain a écrit:
Des spécifications d'exception comme en java ? J'espère bien
que non.
Herb Sutter résume bien bien la situation :
les 2 points sont liés ? Java fait une vérification à la
compil., l'article ne parle que de vérification au runtime.
ma question portait sur un contrôle à la compilation.
Si je me souviens bien, le fait de mettre des specifications
d'exception _force_ le compilateur a insérer des vérifications
au runtime (ce qui conduit à un abort() inconditionel si on
les viole).
|
Il oblige un peu l'équivalent d'un bloc de try autour de la
fonction, oui. Mais le coût d'un bloc de try est zéro sur les
compilateurs que j'utilise d'habitude ; seulement une entrée en
plus dans un tableau et du code qui ne s'exécute que si
l'exception est levée.
--
James Kanze kanze.james (AT) neuf (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
Sylvain Guest
|
Posted: Sun Jul 23, 2006 5:42 am Post subject: Re: Exception [was: Re: Comment rendre une classe "iterable" |
|
|
James Kanze wrote on 23/07/2006 02:13:
| Quote: |
Ce n'est pas tout à fait vrai. Le Java fait une vérification à
la compile pour certaines exceptions, et pas pour d'autres. Et
c'est impossible en Java d'écrire une garantie qu'une fonction
ne sortira pas par une exception, qui est la seule garantie
réelement utile. (Et ça ne me déplairait pas qu'elle soit
enforcée par le compilateur en C++, mais ça ne va pas se faire.)
|
peut-être, dont acte, etc, mais ça ne réponds pas à ma simple question:
est-ce que le pré-précesseur (de M$ à tout le moins) va continuer des
années à me balancer des warnings à la compil. pour ne dire qu'il n'a
rien à faire des info fournies ou peut-on imaginer un jour qu'un
contrôle local / hérité soit réalisé pour une méthode _déclarant_ ses
exceptions.
(je ne parle pas ici d'un nécessaire catch global qui existe dèja, ni de
prétendue incompatibilité avec des codes qui ne déclarant rien n'ont
aucune raison de ne plus marcher).
Sylvain.
ps: les throwable vs exception de Java sont un peu hors sujet vis à vis
du comportement normé d'un compilo C++. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|