Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

2 questions a propos des vecteurs & de leurs initialisations

12 réponses
Avatar
mderie
Bonjour !

Q1) Je voudrais savoir si on peut demander au compilateur d'inferer le
type d'un element d'un vecteur :

template<class T>
class DumpVisitor
{
public:
void operator()(T item)
{
cout << "Item = " << item << endl;
}
};

vector<int> v;
...
for_each(v.begin(), v.end(), DumpVisitor<int>); // OK
for_each(v.begin(), v.end(), DumpVisitor<v.?>); // ?

Le but : definir une macro qui ne prend qu'un parametre, le vector !

Q2) Est-ce qu'avec le TR1 on peut ecrire plus simplement ceci :

vector<int> v;
v.push_back(1900);
v.push_back(1984);
v.push_back(2000);
v.push_back(2007);
v.push_back(2008);

Genre : vector<int> v = { 1900, 1984, 2000, 2007, 2008 };

Un tout grand merci.

10 réponses

1 2
Avatar
Michael DOUBEZ
Bonjour !

Q1) Je voudrais savoir si on peut demander au compilateur d'inferer le
type d'un element d'un vecteur :

template<class T>
class DumpVisitor
{
public:
void operator()(T item)
{
cout << "Item = " << item << endl;
}
};

vector<int> v;
...
for_each(v.begin(), v.end(), DumpVisitor<int>); // OK
for_each(v.begin(), v.end(), DumpVisitor<v.?>); // ?

Le but : definir une macro qui ne prend qu'un parametre, le vector !


Le define vector<>::value_type to donne le type des données que
contients le vecteur.


Q2) Est-ce qu'avec le TR1 on peut ecrire plus simplement ceci :

vector<int> v;
v.push_back(1900);
v.push_back(1984);
v.push_back(2000);
v.push_back(2007);
v.push_back(2008);

Genre : vector<int> v = { 1900, 1984, 2000, 2007, 2008 };


Non mais tu peux le faire avec boost::array (std::tr1::array<>).

boost::array<int,5> v_init = { { 1900,1984, 2000, 2007,2008 } };
vector<int> v(v_init.begin(),v_init.end());

Sinon, il n'est pas trop du de se faire une fonction make_vector<>() qui
prends un tableau en entrée et retourne le vector<> correspondant puis
tu swap.

Michael

Avatar
mderie
On Mar 4, 12:38 pm, Michael DOUBEZ wrote:



Bonjour !

Q1) Je voudrais savoir si on peut demander au compilateur d'inferer le
type d'un element d'un vecteur :

template<class T>
class DumpVisitor
{
public:
void operator()(T item)
{
cout << "Item = " << item << endl;
}
};

vector<int> v;
...
for_each(v.begin(), v.end(), DumpVisitor<int>); // OK
for_each(v.begin(), v.end(), DumpVisitor<v.?>); // ?

Le but : definir une macro qui ne prend qu'un parametre, le vector !


Le define vector<>::value_type to donne le type des données que
contients le vecteur.


Oui mais bon cela m'oblige a ecrire qqch de ridicule :

for_each(v.begin(), v.end(), DumpVisitor<vector<int>::value_type>());

Or v a ete entierement defini...
==> Ma conclusion est donc que non le compilo ne peut pas m'aider:-(

Q2) Est-ce qu'avec le TR1 on peut ecrire plus simplement ceci :

vector<int> v;
v.push_back(1900);
v.push_back(1984);
v.push_back(2000);
v.push_back(2007);
v.push_back(2008);

Genre : vector<int> v = { 1900, 1984, 2000, 2007, 2008 };


Non mais tu peux le faire avec boost::array (std::tr1::array<>).

boost::array<int,5> v_init = { { 1900,1984, 2000, 2007,2008 } };


Non merci : Je dois encore compter moi-meme le nombre d'element du
tableau(ici 5)...

Merci bcp quand meme

vector<int> v(v_init.begin(),v_init.end());

Sinon, il n'est pas trop du de se faire une fonction make_vector<>() qui
prends un tableau en entrée et retourne le vector<> correspondant puis
tu swap.

Michael



Avatar
Michel Decima
On Mar 4, 12:38 pm, Michael DOUBEZ wrote:

Q2) Est-ce qu'avec le TR1 on peut ecrire plus simplement ceci :
vector<int> v;
v.push_back(1900);
v.push_back(1984);
v.push_back(2000);
v.push_back(2007);
v.push_back(2008);
Genre : vector<int> v = { 1900, 1984, 2000, 2007, 2008 };
Non mais tu peux le faire avec boost::array (std::tr1::array<>).


boost::array<int,5> v_init = { { 1900,1984, 2000, 2007,2008 } };


Non merci : Je dois encore compter moi-meme le nombre d'element du
tableau(ici 5)...


Sans le TR1, ni Boost, juste avec 2 fonctions triviales (cf plus bas),
il n'y a pas besoin de compter les elements:

int v_init[] = { 1900, 1984, 2000, 2007, 2008 };
vector< int > v( begin(v_init), end(v_init) ) ;

Les deux fonctions begin et end :

template< typename T, size_t N >
inline T* begin( T (&array)[ N ] )
{ return array ; }

template< typename T, size_t N >
inline T* end( T (&array)[ N ] )
{ return array + N ; }



Avatar
David Côme
On Tue, 04 Mar 2008 12:38:39 +0100, Michael DOUBEZ
wrote:

Genre : vector<int> v = { 1900, 1984, 2000, 2007, 2008 };



Ce genre de chose est faite pour boost::assign.
Exemple.
vector<int> v m= 1900, 1984, 2000, 2007, 2008;

Avatar
James Kanze
On Mar 4, 5:37 pm, David Côme wrote:
On Tue, 04 Mar 2008 12:38:39 +0100, Michael DOUBEZ

wrote:
Genre : vector<int> v = { 1900, 1984, 2000, 2007, 2008 };


Ce genre de chose est faite pour boost::assign.
Exemple.
vector<int> v m= 1900, 1984, 2000, 2007, 2008;


Il n'y a quelque chose là qui ne va pas. C'est quoi comme
syntax ? Au moins qu'il y ait un macro que je ne vois pas, un
compilateur doit émettre une erreur sur cette ligne. « v m »,
je ne crois pas que sans macro, ça peut jamais être légal. (Je
crois qu'il y a quelque chose dans boost qui permet :
v += 1900, 1984, 2000, 2007, 2008 ;
mais ça marche parce que l'opérateur += est surchargé, et qu'il
renvoie quelque chose pour lequel l'opérateur , est surchargé.
L'obfuscation, quoi. Mais dans ton cas, il n'y a pas
d'opérateurs à surcharger.)

--
James Kanze (GABI Software) email:
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


Avatar
Fabien LE LEZ
On Tue, 4 Mar 2008 03:17:04 -0800 (PST), mderie :

template<class T>
class DumpVisitor_T
{ ... };

template <class C> DumpVisitor_T<C::value_type> DumpVisitor (C const&)
{
return DumpVisitor_T<C::value_type>();
}

for_each(v.begin(), v.end(), DumpVisitor<int>); // OK


Je suis quasi-sûr que ça ne fonctionne pas. DumpVisitor<int> est un
type, et une fonction attend un objet en argument. Il faudrait donc
écrire for_each(v.begin(), v.end(), DumpVisitor<int>());

Mais avec le code ci-dessus, on peut écrire :

for_each(v.begin(), v.end(), DumpVisitor(v));


On pourrait même faire mieux :

template <class C> void ForEachDumpVisitor (C& v)
{
for_each (v.begin(), v.end(), DumpVisitor_T<C::value_type>());
}

Avatar
David Côme
On Tue, 04 Mar 2008 18:13:59 +0100, James Kanze
wrote:

On Mar 4, 5:37 pm, David Côme wrote:
On Tue, 04 Mar 2008 12:38:39 +0100, Michael DOUBEZ

wrote:
Genre : vector<int> v = { 1900, 1984, 2000, 2007, 2008 };


Ce genre de chose est faite pour boost::assign.
Exemple.
vector<int> v m= 1900, 1984, 2000, 2007, 2008;


Il n'y a quelque chose là qui ne va pas. C'est quoi comme
syntax ? Au moins qu'il y ait un macro que je ne vois pas, un
compilateur doit émettre une erreur sur cette ligne. « v m »,
je ne crois pas que sans macro, ça peut jamais être légal. (Je
crois qu'il y a quelque chose dans boost qui permet :
v += 1900, 1984, 2000, 2007, 2008 ;
mais ça marche parce que l'opérateur += est surchargé, et qu'il
renvoie quelque chose pour lequel l'opérateur , est surchargé.
L'obfuscation, quoi. Mais dans ton cas, il n'y a pas
d'opérateurs à surcharger.)



Tu as raison James, ya des faute de frappe :D
Sinon voici une exemple complet et minimaliste de boost::assign.

#include <boost/assign/std/vector.hpp> // for 'operator+=()'
#include <boost/assert.hpp>

using namespace std;
using namespace boost::assign;

int main()
{
vector<int> values ;
values += 1900,1984,2000,2007,2008;
}



Avatar
Falk Tannhäuser
mderie schrieb:
On Mar 4, 12:38 pm, Michael DOUBEZ wrote:
Bonjour !
Q1) Je voudrais savoir si on peut demander au compilateur d'inferer le
type d'un element d'un vecteur :
template<class T>
class DumpVisitor
{
public:
void operator()(T item)
{
cout << "Item = " << item << endl;
}
};
vector<int> v;
...
for_each(v.begin(), v.end(), DumpVisitor<int>); // OK
for_each(v.begin(), v.end(), DumpVisitor<v.?>); // ?
Le but : definir une macro qui ne prend qu'un parametre, le vector !
Le define vector<>::value_type to donne le type des données que

contients le vecteur.


Oui mais bon cela m'oblige a ecrire qqch de ridicule :

for_each(v.begin(), v.end(), DumpVisitor<vector<int>::value_type>());

Or v a ete entierement defini...
==> Ma conclusion est donc que non le compilo ne peut pas m'aider:-(


Si, tu peux faire déduire le type à afficher par le compilateur :

struct DumpVisitor
{
std::ostream& o;
DumpVisitor(std::ostream& o = std::cout) : o(o) {}

template<typename T> void operator()(T const& t) const
{
o << "Item = " << t << 'n';
}
};

...
std::vector<int> v;
std::for_each(v.begin(), v.end(), DumpVisitor());


Falk



Avatar
James Kanze
On 4 mar, 18:43, David Côme wrote:
On Tue, 04 Mar 2008 18:13:59 +0100, James Kanze
wrote:


[...]
Sinon voici une exemple complet et minimaliste de boost::assign.

#include <boost/assign/std/vector.hpp> // for 'operator+=()'
#include <boost/assert.hpp>

using namespace std;
using namespace boost::assign;

int main()
{
vector<int> values ;
values += 1900,1984,2000,2007,2008;
}


Ce qui est déroutant, pour le moindre. J'aurais tendance à le
considérer même de l'obfusation et l'abus du surcharge de
l'opérateur. (Mais est-ce qu'il y a jamais des cas de surcharge
de l'opérateur virgule qui ne sont pas d'abus ?)

--
James Kanze (GABI Software) email:
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

Avatar
Falk Tannhäuser
James Kanze wrote:
On 4 mar, 18:43, David Côme wrote:
Sinon voici une exemple complet et minimaliste de boost::assign.

#include <boost/assign/std/vector.hpp> // for 'operator+=()'

using namespace std;
using namespace boost::assign;

int main()
{
vector<int> values ;
values += 1900,1984,2000,2007,2008;
}


Ce qui est déroutant, pour le moindre. J'aurais tendance à le
considérer même de l'obfusation et l'abus du surcharge de
l'opérateur. (Mais est-ce qu'il y a jamais des cas de surcharge
de l'opérateur virgule qui ne sont pas d'abus ?)


Surtout ça donne des résultats "intéressants" dès que les expressions
ayant des effets de bord entrent en jeu :

int i = 0;
values += ++i, ++i, ++i, i--, i--, i--;
std::copy(values.begin(), values.end(),
std::ostream_iterator<int>(std::cout, " "));

m'affiche "1 2 3 3 2 1 " avec GCC et "0 0 0 -2 -1 0 " avec MSVC, et les
deux ont raison...

Falk


1 2