14/06/2008, 14:24
|
| | Fecha de Ingreso: junio-2008
Mensajes: 10
Antigüedad: 16 años, 6 meses Puntos: 0 | |
Ayuda con Funciones objeto (funtores) Tengo un problema con unas prácticas de la librería stl de c++, a ver si me podeis echar un cable. El problema lo tengo con el pokedex.cc ya que las funciones de la clase las tengo que hacer con algoritmos predefinidos de la librería stl de c++. La clase pokemon.cc me compila perfectamente y ya comprobé que todas las funciones están bien con un main así no os pongo el código.
El problema de pokedex.cc esta con los funtores de los accumulate. El profesor me dijo que le un accumulate podia además de sumar enteros o tipos de datos simples le podias ir añadiendo una estructura de datos como map, set o vector. Aqui va el código.
pokedex.h
Código:
#include <iostream>
#include <string>
#include <set>
#include <map>
#include <iterator>
#include <pokemon.h>
#include <utility>
#include <vector>
#include <numeric>
#ifndef _POKEDEX_H
#define _POKEDEX_H
///////////////////////////////////////////////////////////////////////////
//
// Definicion class pokedex
//
///////////////////////////////////////////////////////////////////////////
class pokedex
{
friend ostream & operator<<(ostream &, const pokedex &);
friend istream & operator>>(istream &, pokedex &);
public:
// constructores
pokedex();
// operaciones
const pokemon & info(const string &)const;
/* Necesita: el nombre de un pokemon
Produce: una referencia al objeto pokemon si existe
Error: si no existe debe generarse una excepcion
*/
void fusion(const pokedex &);
/* Necesita: otra coleccion de pokemons
Modifica: la actual aniadiendo los que no estuvieran ya en ella
*/
map<string,int> totales() const;
/* Produce: un diccionario conteniendo como clave los tipos de pokemons que hay y
como valor el numero de pokemons que hay de dicho tipo. Adicionalmente contendra
una entrada con clave "Total" conteniendo el total de pokemons en la coleccion
*/
set<string> tipos() const;
/* Produce: un conjunto conteniendo todos los tipos distintos del pokedex
*/
vector<pokemon> deTipo(const string &) const;
/* Necesita: un tipo de pokemon
Produce: un vector con todos los pokemons de ese tipo
*/
protected:
// area de datos
// cjto de pokemons -> pokemons
set<pokemon> data;
};
ostream & operator<<(ostream &, const pokedex & );
istream & operator>>(istream &, pokedex & );
#endif
pokedex.cc
Código:
#include <pokedex.h>
#include <fstream>
struct funtor_findif {
funtor_findif(const string &n) : name(n) {}
bool operator()(const pokemon &p1) {
if( name==p1.dame_nombre() ) return true;
else return false;
}
string name;
};
struct funtor_accutotales {
map<string,int> operator() (map<string,int> &acum, const pokemon &p1) { // Epera el valor actual del acumulador, y el elemento que toca ahora en la nueva suma, con esto decides tu la nueva suma
pair<string,string> aux=p1.dame_tipos();
acum[aux.first]++;
if ( aux.second != "" ) {
acum[aux.second]++;
}
acum["Total"]++;
return acum;
}
};
struct funtor_accutipos {
set<string> operator() (set<string> &acum, const pokemon &p1) {
pair<string,string> aux=p1.dame_tipos();
acum.insert(acum.begin(),aux.first);
if ( aux.second != "" ) {
acum.insert(acum.begin(),aux.second);
}
return acum;
}
};
struct funtor_accudetipo {
public:
funtor_accudetipo(const string &t) : tipo(t) {}
vector<pokemon> operator() (vector<pokemon> &acum, const pokemon &p1) {
pair<string,string> aux=p1.dame_tipos();
if (aux.first==tipo) acum.push_back(p1);
if (aux.second==tipo) acum.push_back(p1);
return acum;
}
string tipo;
};
pokedex::pokedex() : data()
{
}
// Devuelve un objeto pokemon si existe en el conjunto
const pokemon & pokedex::info(const string & nombre)const {
linea54 set<pokemon>::iterator ret=find_if(data.begin(), data.end(), funtor_findif(nombre));
if ( ret != data.end() ) return *ret;
else {
cout<<"Error: Pokemon no existe"<<endl;
return *(data.end());
}
}
//
void pokedex::fusion(const pokedex & rhs) {
insert_iterator<set<pokemon> > itr_ins(data,data.begin());
set_union(rhs.data.begin(),rhs.data.end(),data.begin(),data.end(),itr_ins);
}
map<string,int> pokedex::totales() const { // accumulate y funcion objeto
// Retorna para cada tipo el numero de pokemons de dicho tipo
linea70 return accumulate(data.begin(), data.end(), map<string,int>(), funtor_accutotales());
}
set<string> pokedex::tipos() const {
/*acumulate y funtor*/
linea75 return accumulate(data.begin(), data.end(), set<string>(), funtor_accutipos());
}
vector<pokemon> pokedex::deTipo(const string & tipo) const {
/*acumulate y funtor*/
linea80 return accumulate(data.begin(), data.end(), vector<pokemon>(), funtor_accudetipo(tipo));
}
El error de compilación es el siguiente: Cita: /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_numeric.h: In function ‘_Tp std::accumulate(_InputIterator, _InputIterator, _Tp, _BinaryOperation) [with _InputIterator = std::_Rb_tree_const_iterator<pokemon>, _Tp = std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >, _BinaryOperation = funtor_accutotales]’: pokedex.cc:70: instantiated from here
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_numeric.h:116: error: no hay coincidencia para la llamada a ‘(funtor_accutotales) (std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >&, const pokemon&)’
pokedex.cc:14: nota: los candidatos son: std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > > funtor_accutotales::operator()(std::map<std::basic _string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >, pokemon&) pokedex.cc:75: instantiated from here
<lo mismo que antes> pokedex.cc:80: instantiated from here
<lo mismo que antes> pokedex.cc:54: instantiated from here
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:188: error: no hay coincidencia para la llamada a ‘(funtor_findif) (const pokemon&)’
pokedex.cc:6: nota: los candidatos son: bool funtor_findif::operator()(pokemon&)
Gracias de antemano.
EDITADO: YA FUNCIONA!!!
Última edición por shacklebolt; 16/06/2008 a las 02:31 |