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

map + key sous forme de pointeur + const...

3 réponses
Avatar
Etienne
Bonjours,

J'ai un programme super simple :

#include <iostream>
#include <map>

void pouet(const int* &)
{
}

int main(void)
{
std::map<int*, std::string> po;
const int t =3D 5;
const int * p=3D &t;
pouet(p);
po.find(p);

return 0;
}

qui ne compile pas (ni gcc 4.x, ni gcc 3.x) :

t=2Ecc: In function =ABint main()":
t=2Ecc:14: erreur: invalid conversion from =ABconst int*" to =ABint*"
t=2Ecc:14: erreur: initializing argument 1 of =ABtypename
std::_Rb_tree<_Key, std::pair<const _Key, _Tp>,
std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename
_Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator
std::map<_Key, _Tp, _Compare, _Alloc>::find(const _Key&) [with _Key =3D
int*, _Tp =3D std::basic_string<char, std::char_traits<char>,
std::allocator<char> >, _Compare =3D std::less<int*>, _Alloc =3D
std::allocator<std::pair<int* const, std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > >]"

Par contre :
1) si je remplace mon int * pour un int cela compile.
2) si je d=E9clare ma map : std::map<int const*, std::string> cela
compile.

Pour cela ne compile pas sous sa premi=E8re forme ?

Merci d'avance
Etienne

3 réponses

Avatar
Michel Decima
Bonjours,

J'ai un programme super simple :

#include <iostream>
#include <map>

void pouet(const int* &)
{
}

int main(void)
{
std::map<int*, std::string> po;
const int t = 5;
const int * p= &t;
pouet(p);
po.find(p);

return 0;
}

qui ne compile pas (ni gcc 4.x, ni gcc 3.x) :

Pour cela ne compile pas sous sa première forme ?


Pour la meme raison que celui-ci, qui ne compile pas non plus:

typedef int* Key;

int main(void)
{
const int t = 5;
const int* p= &t;
const Key q = &t;
}

Pour la map, la cle est int*, cad pointeur sur int, et tu lui donne un
const int*, cad pointeur sur int constant (c'est la valeur pointee qui
est const). Cette conversion n'est pas valide.

Ta fonction pouet() et map::find() ne prennent pas leur argument
de la meme maniere: Pour pouet, c'est une reference sur un pointeur
vers un entier constant, Pour map find c'est une reference constante sur
le type clé, qui se trouve etre ici un pointeur vers un entier (non
constant).

Pour voir la difference sans difficulté, tu peux ecrire "const" apres
le type (const int est equivalent a int const), et lire de droite a
gauche. Avec cette convention:

void pouet( int const* & );
iterator find( int* const& );

int const t = 5;
int const* p = &t;

Avatar
Michael DOUBEZ
Bonjours,

J'ai un programme super simple :

#include <iostream>
#include <map>

void pouet(const int* &)
{
}

int main(void)
{
std::map<int*, std::string> po;
const int t = 5;
const int * p= &t;
pouet(p);
po.find(p);

return 0;
}

qui ne compile pas (ni gcc 4.x, ni gcc 3.x) :

t.cc: In function «int main()":
t.cc:14: erreur: invalid conversion from «const int*" to «int*"
t.cc:14: erreur: initializing argument 1 of «typename
std::_Rb_tree<_Key, std::pair<const _Key, _Tp>,
std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename
_Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator
std::map<_Key, _Tp, _Compare, _Alloc>::find(const _Key&) [with _Key > int*, _Tp = std::basic_string<char, std::char_traits<char>,
std::allocator<char> >, _Compare = std::less<int*>, _Alloc > std::allocator<std::pair<int* const, std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > >]"

Par contre :
1) si je remplace mon int * pour un int cela compile.
2) si je déclare ma map : std::map<int const*, std::string> cela
compile.

Pour cela ne compile pas sous sa première forme ?


Parce que les type ne correspondent pas:
- dans la map, la clé est 'un pointeur sur un entier'
- dans find, le parametre est une référence const sur 'un pointeur
sur un entier const'

Michael

Avatar
Etienne
Merci...

Etienne (un peu moins bête de jour en jour)