PDA

Visualizza la versione completa : [c++ stl]map e functor argument


giuseppe500
12-02-2010, 14:30
ciao,
ho una mappa :
map<int, CCartesianPointIfc*> m_PointsPoly;
dove ccartesianpointifc una mia classe , vorrei utilizzare un functor del tipo:
[code]
class TransformProfile {
private:
C3DMatrix m_pMxTransformMatrix;
public:
TransformProfile(C3DMatrix& mxTransformMatrix): m_pMxTransformMatrix(mxTransformMatrix){;};
void operator()(int pos, CCartesianPointIfc* p){
C3DVector v3d(p->GetPoint(0), p->GetPoint(1), p->GetPoint(3));
C3DVector v3dpRes = m_pMxTransformMatrix * v3d ;
p->SetPoint(0, v3dpRes.x);
p->SetPoint(1, v3dpRes.y);
p->SetPoint(2, v3dpRes.z);
}
};
[code]
per trasformare le coordinate di una polilinea nello spazio passando una matrice.
void CPolylineIfc::GetTransformedPoints(C3DMatrix mx)
{
for_each(m_PointsPoly.begin(),m_PointsPoly.end(),T ransformProfile(mx));
}
mi da quest errore:
c:\Programmi\Microsoft Visual Studio .NET 2003\Vc7\include\algorithm(21): error C2064: term does not evaluate to a function taking 1 arguments


posso applicare anche alla mappa i functori come al vector?
come faccio con gli argomenti dato che una mappa ha due valori a differenza del vector?
grazie.

shodan
12-02-2010, 16:53
Il functor deve ricevere una std::pair, quindi:


void operator()(std::pair<int, CCartesianPointIfc*>& p) {

p.first <-- la chiave
p.second <-- il puntatore.

}

giuseppe500
26-05-2010, 14:23
Il functor deve ricevere una std::pair, quindi:
codice:

void operator()(std::pair<int, CCartesianPointIfc*>& p) {

p.first <-- la chiave
p.second <-- il puntatore.

}



ma come faccio ad es a costruire un function object di confronto tipo il less per intenderci con solo un parametro?
ho provato cosi:



struct giugio
{
int id;
string str;
string str2;

};
struct oper
{
bool operator()(std::pair<int, giugio>& p, std::pair<int, giugio>& p1) const
{
return p.second.id < p1.second.id;
}
};
.
.
typedef map<int,giugio,oper> intV;
intV v, v2, v3Union;
.
.



ma ottengo qest' errore:
c:\Programmi\Microsoft Visual Studio .NET 2003\Vc7\include\map(144): error C2664: 'bool oper::operator ()(std::pair<_Ty1,_Ty2> &,std::pair<_Ty1,_Ty2> &) const' : cannot convert parameter 1 from 'const std::map<_Kty,_Ty,_Pr>::key_type' to 'std::pair<_Ty1,_Ty2> &'
with
[
_Ty1=int,
_Ty2=giugio
]
and
[
_Kty=int,
_Ty=giugio,
_Pr=oper
]
and
[
_Ty1=int,
_Ty2=giugio
]

shodan
26-05-2010, 19:41
Quel functor non funziona con la std::map.


template < class Key, class T, class Compare = less<Key>,
class Allocator = allocator<pair<const Key,T> > > class map;


Il functor si limita a confrontare le chiavi, non le coppie contenute nella mappa.
Ma che devi fare esattamente?

giuseppe500
26-05-2010, 21:02
vorrei usare le funzioni set_difference , union ecc.. sui due vettori di input mappa1 e mappa2 e mettere i risultati in mappaFinale.



typedef map<int, object*> intV;
intV mappa1, mappa2, mappaFinale;

mappa1[0] = new object A(0, 0,0, "testo stringa0")
mappa1[2] = new object A(2, 2,2, "testo stringa2")
mappa1[4] = new object A(4, 4,4, "testo stringa4")

mappa2[0] = new object A(2, 4,5, "testo stringa0seconda")
mappa2[2] = new object A(2, 4,5, "testo stringa1seconda")
mappa2[4] = new object A(2, 4,5, "testo stringa4seconda")

cosi:
intV::iterator it = mappafinale.begin();
set_difference(mappa1.begin(),mappa1.end(),mappa2. begin(),mappa2.end(),
insert_iterator<intV>(mappafinale,it));


vector<int>::iterator itOut;
for(itOut= mappaFinale.begin();itOut!= mappaFinale.end();++itOut)
std::cout << *itOut<< "\n";


in base pero' all' indice , ovvero tenere conto dell indicemappa1 / indicemappa2 e non dei dati(svariati e non relativi alle funzioni di insiemi dell std di object).

come si puo fare?
grazie.

shodan
26-05-2010, 23:05
Scusa, ma continuo a non capire. Partendo da questo:


mappa1[0] = new object A(0, 0,0, "testo stringa0")
mappa1[2] = new object A(2, 2,2, "testo stringa2")
mappa1[4] = new object A(4, 4,4, "testo stringa4")

mappa2[0] = new object A(2, 4,5, "testo stringa0seconda")
mappa2[2] = new object A(2, 4,5, "testo stringa1seconda")
mappa2[4] = new object A(2, 4,5, "testo stringa4seconda")


e usando ad esempio set_difference, che risultato vorresti ottenere?

giuseppe500
27-05-2010, 10:40
Scusa, ma continuo a non capire. Partendo da questo:
codice:

mappa1[0] = new object A(0, 0,0, "testo stringa0")
mappa1[2] = new object A(2, 2,2, "testo stringa2")
mappa1[4] = new object A(4, 4,4, "testo stringa4")

mappa2[0] = new object A(2, 4,5, "testo stringa0seconda")
mappa2[2] = new object A(2, 4,5, "testo stringa1seconda")
mappa2[4] = new object A(2, 4,5, "testo stringa4seconda")



e usando ad esempio set_difference, che risultato vorresti ottenere?


vorrei ottenere un array finale vuoto perch gli indici di mappa1 e gli indici di mappa2 sono gli stessi , non ce n' di piu' ne di meno.



mappa1[0] = new object A(0, 0,0, "testo stringa0")
mappa1[2] = new object A(2, 2,2, "testo stringa2")
mappa1[4] = new object A(4, 4,4, "testo stringa4")
mappa1[5] = new object A(4, 4,4, "testo stringa5")

mappa2[0] = new object A(2, 4,5, "testo stringa0seconda")
mappa2[2] = new object A(2, 4,5, "testo stringa1seconda")
mappa2[4] = new object A(2, 4,5, "testo stringa4seconda")


cosi con difference vorrei ottenere un array finale con un elemento al'indice 5 con un object 4,4,4 "testo stringa5"
con un union vorrei ottenere:

indice 0=> A(0, 0,0, "testo stringa0")
indice2=> A(2, 2,2, "testo stringa2")
indice4=> A(4, 4,4, "testo stringa4")
indice5=> A(4, 4,4, "testo stringa5")

non mi inporta nella differenza o nell' union la classe object per la ricerca della differenza o dell'union.


grazie.

giuseppe500
27-05-2010, 13:18
il problema adesso che se faccio l'intersezione di due mappe gli elementi devono essere uguali se voglio che vengano intersecati , se la chiave la stessa, ma il valore diverso non interseca.
ciao.

shodan
27-05-2010, 14:10
Ok. Adesso chiaro.
http://www.cplusplus.com/reference/algorithm/set_difference/
Come vedi dal link, la set_difference in overload. La seconda versione prende una funzione o function object per il confronto (stessa cosa per la set_union
Riprendendo il tuo codice, diventa.


///////////////////////////////////////////////////////////
// Function object
struct mycmp {
bool operator () (const pair<int,object*>& a, const pair<int,object*>& b) {
return a.first < b.first;
}
};

////////////////////////////////////////////////////////////

typedef map<int, object*> intV;
intV mappa1, mappa2, mappaFinale;

mappa1[0] = new object A(0, 0,0, "testo stringa0")
mappa1[2] = new object A(2, 2,2, "testo stringa2")
mappa1[4] = new object A(4, 4,4, "testo stringa4")

mappa2[0] = new object A(2, 4,5, "testo stringa0seconda")
mappa2[2] = new object A(2, 4,5, "testo stringa1seconda")
mappa2[4] = new object A(2, 4,5, "testo stringa4seconda")

//cosi:
intV::iterator it = mappafinale.begin();
set_difference(mappa1.begin(),mappa1.end(),mappa2. begin(),mappa2.end(),
inserter(mappafinale,it), mycmp() );

//o direttamente nel vector (dev'essere di std::pair).

vector< pair<int, object*> > vectorfinale;
set_difference(mappa1.begin(),mappa1.end(),mappa2. begin(),mappa2.end(),
back_inserter(mappafinale), mycmp() );

Loading