OVH Cloud OVH Cloud

Afficher le contenu d'une std::list ?

10 réponses
Avatar
Stephane Wirtel
Bonjour à tous,

En regardant dans les exemples de Boost::Any, j'ai créé une liste contenant des données de types différents.

Par exemple le code suivant (imaginé de toute pièce) fonctionne (car testé hier soir).


template <typename dataType> class Field {
public:
Field (const std::string& pFieldName) : mFieldName (pFieldName), mFieldValue (dataType ()) {
}
~Field () {
}
const std::string& getName () const {
return mFieldName;
}
dataType getValue () {
return mFieldValue;
}
private:
dataType mFieldValue;
std::string mFieldName;
};

typedef std::list <boost::any> Many;

Many many;
many.push_back (Field <int> ("Age"));
many.push_back (Field <bool> ("IsValue"));

Mon soucis est que lorsque je désire afficher le contenu de la liste des Field
se trouvant dans ma std::list, j'ai une erreur lors de la compilation me disant
que mon getValue et getName ne sont pas joignable.

Donc, par exemple, ceci ne fonctionne pas :|

for (Many::iterator it = many.begin (); it != many.end (); ++it) {
std::cout << "Name : " << it->getName () << std::endl;
std::cout << " Value : " << it->getValue () << std::endl;
}

Peut-être avez-vous déjà songé à ce problème, mais auriez-vous peut-être déjà trouvé une solution ?
En tout cas, ce soir en rentrant du boulot, je regarderai encore pour trouver une solution à mon problème.

Bonne soirée,

Stéphane

10 réponses

Avatar
Stan
"Stephane Wirtel" a écrit dans le message de
news:dbgiko$587$
| Bonjour à tous,
|
| En regardant dans les exemples de Boost::Any, j'ai créé une liste
contenant des données de types différents.
|
| Par exemple le code suivant (imaginé de toute pièce) fonctionne (car testé
hier soir).
|
|
| template <typename dataType> class Field {
| public:
| Field (const std::string& pFieldName) : mFieldName (pFieldName),
mFieldValue (dataType ()) {
| }
| ~Field () {
| }
| const std::string& getName () const {
| return mFieldName;
| }
| dataType getValue () {
| return mFieldValue;
| }
| private:
| dataType mFieldValue;
| std::string mFieldName;
| };
|
| typedef std::list <boost::any> Many;
|
| Many many;
| many.push_back (Field <int> ("Age"));
| many.push_back (Field <bool> ("IsValue"));
|
| Mon soucis est que lorsque je désire afficher le contenu de la liste des
Field
| se trouvant dans ma std::list, j'ai une erreur lors de la compilation me
disant
| que mon getValue et getName ne sont pas joignable.
|
| Donc, par exemple, ceci ne fonctionne pas :|
|
| for (Many::iterator it = many.begin (); it != many.end (); ++it) {
| std::cout << "Name : " << it->getName () << std::endl;
| std::cout << " Value : " << it->getValue () << std::endl;
| }
|
| Peut-être avez-vous déjà songé à ce problème, mais auriez-vous peut-être
déjà trouvé une solution ?
| En tout cas, ce soir en rentrant du boulot, je regarderai encore pour
trouver une solution à mon problème.
|

for (Many::iterator it = many.begin (); it != many.end (); ++it) {
std::cout << "Name : " << it.getName () << std::endl;
std::cout << " Value : " << it.getValue () << std::endl;
}


--
-Stan
Avatar
Stan
"Stephane Wirtel" a écrit dans le message de
news:dbgiko$587$
| Bonjour à tous,
|
| En regardant dans les exemples de Boost::Any, j'ai créé une liste
contenant des données de types différents.
|
| Par exemple le code suivant (imaginé de toute pièce) fonctionne (car testé
hier soir).
|
|
| template <typename dataType> class Field {
| public:
| Field (const std::string& pFieldName) : mFieldName (pFieldName),
mFieldValue (dataType ()) {
| }
| ~Field () {
| }
| const std::string& getName () const {
| return mFieldName;
| }
| dataType getValue () {
| return mFieldValue;
| }
| private:
| dataType mFieldValue;
| std::string mFieldName;
| };
|
| typedef std::list <boost::any> Many;
|
| Many many;
| many.push_back (Field <int> ("Age"));
| many.push_back (Field <bool> ("IsValue"));
|
| Mon soucis est que lorsque je désire afficher le contenu de la liste des
Field
| se trouvant dans ma std::list, j'ai une erreur lors de la compilation me
disant
| que mon getValue et getName ne sont pas joignable.
|
| Donc, par exemple, ceci ne fonctionne pas :|
|
| for (Many::iterator it = many.begin (); it != many.end (); ++it) {
| std::cout << "Name : " << it->getName () << std::endl;
| std::cout << " Value : " << it->getValue () << std::endl;
| }
|
| Peut-être avez-vous déjà songé à ce problème, mais auriez-vous peut-être
déjà trouvé une solution ?
| En tout cas, ce soir en rentrant du boulot, je regarderai encore pour
trouver une solution à mon problème.
|


for (Many::iterator it = many.begin (); it != many.end (); ++it) {
std::cout << "Name : " << (*it).getName () << std::endl;
std::cout << " Value : " << (*it).getValue () << std::endl;
}

Mais il y a mieux.

--

Stan .
Avatar
Falk Tannhäuser
Stephane Wirtel wrote:
Donc, par exemple, ceci ne fonctionne pas :|

for (Many::iterator it = many.begin (); it != many.end (); ++it) {
std::cout << "Name : " << it->getName () << std::endl;
std::cout << " Value : " << it->getValue () << std::endl;
}


for(Many::iterator it = many.begin(); it != many.end(); ++it)
{
if(Field<int>* f = boost::any_cast<Field<int> >(&*it))
{
std::cout << "Name : " << f->getName();
std::cout << " Value : " << f->getValue() << 'n';
}else if(Field<bool>* f = boost::any_cast<Field<bool> >(&*it))
{
std::cout << "Name : " << f->getName();
std::cout << " Value : " << f->getValue() << 'n';
}
}

mais c'est moche car il faut ajouter un nouveau test pour chaque nouveau type.

Pourquoi pas tout simplement

class FieldBase
{
public:
virtual std::string const& getName() const = 0;
virtual void printValue(std::ostream&) const = 0;
virtual ~FieldBase() {}
}; // class FieldBase

std::ostream& operator<<(std::ostream& o, FieldBase const& f) { f.printValue(o); return o; }

template <typename dataType> class Field : public FieldBase
{
public:
Field(const std::string& pFieldName) : mFieldValue(dataType()), mFieldName(pFieldName) {}
~Field() {}
std::string const& getName() const { return mFieldName; }
dataType getValue() const { return mFieldValue; }
void printValue(std::ostream& o) const { o << getValue(); }

private:
dataType mFieldValue;
std::string mFieldName;
}; // class Field


template<typename T> boost::shared_ptr<T> make_shared_ptr(T* p) { return boost::shared_ptr<T>(p); }
typedef std::list<boost::shared_ptr<FieldBase> > Many;

...
Many many;
many.push_back(make_shared_ptr(new Field<int>("Age")));
many.push_back(make_shared_ptr(new Field<bool>("IsValue")));

for(Many::iterator it = many.begin(); it != many.end(); ++it)
{
std::cout << "Name : " << (**it).getName();
std::cout << " Value : " << **it << 'n';
}

Falk

Avatar
Matthieu Moy
"Stéphane Wirtel" writes:

quel est la diff entre (*it).getValue () et it->getValue () ?


Avec des vrais pointeurs, aucune.

Avec des types définis par l'utilisateur, en surchargeant les
opérateurs "*" et "->", c'est la responsabilité de l'utilisateur de
faire en sorte que ce soit la même chose. En général, c'est le cas.

Pour un contre-exemple (laid, j'en conviens) :


#include <iostream>

using namespace std;

struct bar {
void f() {cout << "bar::f" << endl;}
};

struct foo {
bar * operator -> () {
cout << "->" << endl;
return new bar();
}

bar& operator * () {
cout << "*" << endl;
return *(new bar());
}
};

int main() {
foo F;
F->f();
(*F).f();
}

--
Matthieu

Avatar
Stephane Wirtel
Merci pour la solution,

L'idée est de pouvoir créer une liste de champs d'une table, afin de ne plus devoir les introduire à
la main dans la requête SQL, ce qui me permettrait de diminuer les erreurs dans les requetes SQL.

Sinon, est-ce que quelqu'un connait une lib qui fait environ ce que j'aimerais ?


Encore merci,

Stéphane
Avatar
Stephane Wirtel
Je suis tout à fait d'accord avec toi, mais dans le cas de boost::any, rien ne change.
Avatar
Matthieu Moy
"Stéphane Wirtel" writes:

Je viens de regarder plus attentivement, [...]


Merci de citer la partie pertinente du message auquel tu réponds.
Sinon, on ne sait pas de quoi tu parles ...

--
Matthieu

Avatar
Stan
"Stephane Wirtel" a écrit dans le message de
news: dbguam$b65$
Merci pour la solution,

L'idée est de pouvoir créer une liste de champs d'une table, afin de ne
plus devoir les introduire à la main dans la requête SQL, ce qui me
permettrait de diminuer les erreurs dans les requetes SQL.

Sinon, est-ce que quelqu'un connait une lib qui fait environ ce que
j'aimerais ?




Ce que tu veux faire semble être un wrapper.
Il en existe :

http://www.alhem.net/project/mysql/index.html

--
-Stan

Avatar
Matthieu Moy
"Stéphane Wirtel" writes:

Excuse moi mathieu,


Tu récidives, là ;-).

http://www.giromini.org/usenet-fr/repondre.html

--
Matthieu

Avatar
Stephane Wirtel
Matthieu Moy wrote:
"Stéphane Wirtel" writes:


Excuse moi mathieu,



Tu récidives, là ;-).

http://www.giromini.org/usenet-fr/repondre.html


Possible ;-)

Faut dire, t'as vu l'heure ;-) D'habitude, je me lève plutôt :-)

Désolé pour la faute dans ton prénom,

Stef