Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Ayuda con Funciones objeto (funtores)

Estas en el tema de Ayuda con Funciones objeto (funtores) en el foro de C/C++ en Foros del Web. 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 ...
  #1 (permalink)  
Antiguo 14/06/2008, 14:24
 
Fecha de Ingreso: junio-2008
Mensajes: 10
Antigüedad: 15 años, 10 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
  #2 (permalink)  
Antiguo 14/06/2008, 14:30
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: Ayuda con Funciones objeto (funtores)

Cuando invocas el accumulate, te esta reclamando respecto al set<string>, deberian ser set<pokemon>, pues asi esta definido data.
  #3 (permalink)  
Antiguo 14/06/2008, 14:42
 
Fecha de Ingreso: junio-2008
Mensajes: 10
Antigüedad: 15 años, 10 meses
Puntos: 0
Respuesta: Ayuda con Funciones objeto (funtores)

Supongo que te refieres a esta función:

set<string> tipos() const;
/* Produce: un conjunto conteniendo todos los tipos distintos del pokedex
*/

lo que quiero ir acumulando es los distintos tipos de pokemon sin repeticion en un conjunto, sólo tipos de pokemon, es decir string, por ello debo ir acumulando un set<string> no?

Gracias por contestar

Ah y otra pregunta que quiero hacer. ¿La forma de ir guardando en el funtor un campo es la correcta?

Es que no entiendo nada del error de compilación parece ser que no estoy devolviendo algo correcto pero por lo que vi en la web stl el accumulate retorna el tipo de dato que se va acumulando, en el caso de mis funciones: map<string,int>, set<string> y vector<pokemon>

Última edición por shacklebolt; 14/06/2008 a las 14:49
  #4 (permalink)  
Antiguo 14/06/2008, 15:12
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: Ayuda con Funciones objeto (funtores)

Tal vez convendria cambiar la firma del metodo

map<string,int> operator() (map<string,int> acum, pokemon &p1)

a

map<string,int> operator() (map<string,int> &acum, const pokemon &p1)

Podrias cambiarlo y revisar cual es el reclamo del compilador en ese caso?
  #5 (permalink)  
Antiguo 15/06/2008, 02:05
 
Fecha de Ingreso: junio-2008
Mensajes: 10
Antigüedad: 15 años, 10 meses
Puntos: 0
Respuesta: Ayuda con Funciones objeto (funtores)

Ok ya lo he cambiado tiene sentido porque a cada vez que se llama al operador se va modificando al acumulador pero bueno aunque lo pasara por valor con no poner const valdría. Me sigue dando los mismos errores. Un problema puede estar porque declaro mal los campos de los funtores por los cuales comparo:
string name; en el funtor_findif de la funcion info
string tipo; en el funtor_accudetipo de la funcion Detipo

Estas son las webs de las cuales me informe para hacer el código:
http://www.sgi.com/tech/stl/accumulate.html
http://www.sgi.com/tech/stl/find_if.html

¿Sabeis de alguna web en español que contenga información sobre la stl o ejemplos de programas que usen estos algoritmos predefinidos modificados con funtores?
  #6 (permalink)  
Antiguo 15/06/2008, 06:08
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: Ayuda con Funciones objeto (funtores)

No deberia darte los mismos errores, puesto que el cambio implica un cambio de firma de los metodos, podrias copiar los errores, tal como aparecen en la salida?
Es extraño que una vez cambiados los metodos, ellos no sean encontrados por el compilador. Tal vez el mensaje de error arroje pistas. Haz el cambio propuesto, compila y copia aqui los mensajes asociados solo a ese cambio.
  #7 (permalink)  
Antiguo 15/06/2008, 08:30
 
Fecha de Ingreso: junio-2008
Mensajes: 10
Antigüedad: 15 años, 10 meses
Puntos: 0
Respuesta: Ayuda con Funciones objeto (funtores)

Ya he hecho los cambios que comentastes en los funtores:

Código:
struct funtor_findif {
	funtor_findif(const string &n) : name(n) {} 
	bool operator()(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, 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, 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, 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;
};
y el compilador:

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&)
/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::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, _BinaryOperation = funtor_accutipos]’:
pokedex.cc:75: 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_accutipos) (std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, const pokemon&)’
pokedex.cc:26: nota: los candidatos son: std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > funtor_accutipos::operator()(std::set<std::basic_s tring<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, pokemon&)
/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::vector<pokemon, std::allocator<pokemon> >, _BinaryOperation = funtor_accudetipo]’:
pokedex.cc:80: 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_accudetipo) (std::vector<pokemon, std::allocator<pokemon> >&, const pokemon&)’
pokedex.cc:39: nota: los candidatos son: std::vector<pokemon, std::allocator<pokemon> > funtor_accudetipo::operator()(std::vector<pokemon, std::allocator<pokemon> >&, pokemon&)
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h: In function ‘_InputIterator std::__find_if(_InputIterator, _InputIterator, _Predicate, std::input_iterator_tag) [with _InputIterator = std::_Rb_tree_const_iterator<pokemon>, _Predicate = funtor_findif]’:
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:338: instantiated from ‘_InputIterator std::find_if(_InputIterator, _InputIterator, _Predicate) [with _InputIterator = std::_Rb_tree_const_iterator<pokemon>, _Predicate = funtor_findif]’
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&)
  #8 (permalink)  
Antiguo 15/06/2008, 09:05
 
Fecha de Ingreso: junio-2008
Mensajes: 10
Antigüedad: 15 años, 10 meses
Puntos: 0
Respuesta: Ayuda con Funciones objeto (funtores)

Por si ayuda pongo también la clase pokemon pero ya dije que no tiene ningún problema ya está compilado y comprobado con un main, pero igual os sirve de ayuda.

pokemon.h
Código:
#include <iostream>
#include <string>
#include <utility>

using namespace std;

#ifndef _POKEMON_H
#define _POKEMON_H

class pokemon {
public:
	pokemon();
	pokemon(const int, const string, const string, const string="");

	// Observadores
	int dame_numero() const;
	string dame_nombre() const;
	pair<string,string> dame_tipos() const;

	// Modificadores de campo
	void mete_numero(const int);
	void mete_nombre(const string);
	void mete_tipos(const pair<string,string>);

private:
	int numero;
	string nombre;
	pair<string,string> tipos;
};

// Operadores de lectura y escritura
istream & operator >> (istream & , pokemon & );
ostream & operator << (ostream & , const pokemon & );

// Operador <
bool operator < (const pokemon &, const pokemon &);
pokemon.cc
Código:
#include <pokemon.h>
#include <fstream>

pokemon::pokemon() : numero(-1), nombre(""), tipos("","") {}

pokemon::pokemon(const int num, string nom, const string t1, const string t2) 
	: numero(num), nombre(nom), tipos(t1,t2) {}

int pokemon::dame_numero() const {
	return numero;
} 

string pokemon::dame_nombre() const {
	return nombre;
} 

pair<string,string> pokemon::dame_tipos() const {
	return tipos;
}

void pokemon::mete_numero(const int num) {
	numero=num;
} 

void pokemon::mete_nombre(const string nom) {
	nombre=nom;
} 

void pokemon::mete_tipos(const pair<string,string> tps) {
	tipos=tps;
}

istream & operator >> (istream & in, pokemon & p) {
	int num,ntipos;
	string nom,t1,t2;
	in>>num;
	in>>nom;
	in>>ntipos;
	if ( ntipos == 2 ) {
	in>>t1;
	in>>t2;
	}
	else{
	in>>t1;
	t2="";
	}
	pokemon aux(num,nom,t1,t2);
	p=aux;
	return in;	
}

ostream & operator << (ostream & out, const pokemon & p) {
	out<<p.dame_numero()<<"\t"<<p.dame_nombre()<<"\t";

	if ( p.dame_tipos().second == "") {
		out<<"1\t"<<p.dame_tipos().first;
	}
	else {
		out<<"2\t"<<p.dame_tipos().first<<"\t"<<p.dame_tipos().second;
	}
	return out;
}

bool operator < (const pokemon & pok1, const pokemon &pok2) {
	if(pok1.dame_numero()<pok2.dame_numero()) return true;
	else return false;
}
#endif
editado: YA FUNCIONA!!

Última edición por shacklebolt; 16/06/2008 a las 02:30
  #9 (permalink)  
Antiguo 15/06/2008, 09:20
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: Ayuda con Funciones objeto (funtores)

Hola de nuevo, veo que no esta hecha la modificacion sugerida, realmente.
Tal vez el mensaje de error seria similar finalmente, no lo se, porque quien compila eres tu, pero el codigo mostrado no incluye un const en el segundo parametro que el compilador lo reclama como distinto. El codigo enviado te "delata".

map<string,int> operator() (map<string,int> &acum, const pokemon &p1)
  #10 (permalink)  
Antiguo 15/06/2008, 12:15
 
Fecha de Ingreso: junio-2008
Mensajes: 10
Antigüedad: 15 años, 10 meses
Puntos: 0
Respuesta: Ayuda con Funciones objeto (funtores)

soy TONTO y estoy CIEGO MUCHISIMAS GRACIAS CalgaryCorpus no me di cuenta de ese const que me pusistes jodeeeeeeeeer y el error de compilación al ser tan grande me liaba...

os pongo el código final que compila perfectamente:

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 {
	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
	return accumulate(data.begin(), data.end(), map<string,int>(), funtor_accutotales());
}

set<string> pokedex::tipos() const {
	/*acumulate y funtor*/
	return accumulate(data.begin(), data.end(), set<string>(), funtor_accutipos());
}

vector<pokemon> pokedex::deTipo(const string & tipo) const {
	/*acumulate y funtor*/
	return accumulate(data.begin(), data.end(), vector<pokemon>(), funtor_accudetipo(tipo));
}

ostream & operator<<(ostream &out, const pokedex &px) {
	ostream_iterator<pokemon> itr_out(out,"\n");
	copy(px.data.begin(),px.data.end(),itr_out);
	return out;
}

istream & operator>>(istream &in, pokedex &px) {
	while(!in.eof()){
	pokemon aux;
	in>>aux;
	px.data.insert(aux);
	}
	return in;
}

Última edición por shacklebolt; 15/06/2008 a las 13:16
  #11 (permalink)  
Antiguo 15/06/2008, 13:14
 
Fecha de Ingreso: junio-2008
Mensajes: 10
Antigüedad: 15 años, 10 meses
Puntos: 0
Respuesta: Ayuda con Funciones objeto (funtores)

Bueno ahora tengo otro problemilla he hecho un main para probrar que funcionan los métodos del pokedex tal que así:

Código:
#include <map>
#include <pokemon.h>
#include <pokedex.h>
#include <fstream>

using namespace std;

int main() {
	pokedex pok1;
	ifstream in;
	in.open("pokemons.txt");
	in>>pok1;
	map<string,int> auxmap;
	auxmap=pok1.totales();
	cout<<auxmap["planta"]<<endl;
	return 0;
}
y al intentar compilarlo con esto:
$> g++ -g mainpokedex.cc -I . pokemon.o pokedex.o -o test

me salta con esto:
Cita:
./pokemon.h:7: error: redefinición de ‘class pokemon’
./pokemon.h:7: error: definición previa de ‘class pokemon’
Me parece que la sobrecarga del operador>> de entrada del pokedex puede dar algún problema pero nose.
La linea 7 del pokemon.h es la linea de "class pokemon {" cuando se define la clase. Ninguna otra vez me había salido error semejante he recompilado pokemon.cc y pokedex.cc y nada. ¿Alguna idea?
  #12 (permalink)  
Antiguo 15/06/2008, 13:20
 
Fecha de Ingreso: junio-2008
Mensajes: 10
Antigüedad: 15 años, 10 meses
Puntos: 0
Respuesta: Ayuda con Funciones objeto (funtores)

Cita:
Iniciado por shacklebolt Ver Mensaje
Bueno ahora tengo otro problemilla he hecho un main para probrar que funcionan los métodos del pokedex tal que así:

Código:
#include <map>
#include <pokemon.h>
#include <pokedex.h>
#include <fstream>

using namespace std;

int main() {
	pokedex pok1;
	ifstream in;
	in.open("pokemons.txt");
	in>>pok1;
	map<string,int> auxmap;
	auxmap=pok1.totales();
	cout<<auxmap["planta"]<<endl;
	return 0;
}
y al intentar compilarlo con esto:
Cita:
$> g++ -g mainpokedex.cc -I . pokemon.o pokedex.o -o test
me salta con esto:


Me parece que la sobrecarga del operador>> de entrada del pokedex puede dar algún problema pero nose.
La linea 7 del pokemon.h es la linea de "class pokemon {" cuando se define la clase. Ninguna otra vez me había salido error semejante he recompilado pokemon.cc y pokedex.cc y nada. ¿Alguna idea?
  #13 (permalink)  
Antiguo 15/06/2008, 20:09
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: Ayuda con Funciones objeto (funtores)

En pokemon.h incluye las lineas

#ifndef POKEMON_H
#define POKEMON_H

// ... copiar el codigo original

#endif

para que al ser incluido 2 veces no sea redefinida la clase.
  #14 (permalink)  
Antiguo 16/06/2008, 02:35
 
Fecha de Ingreso: junio-2008
Mensajes: 10
Antigüedad: 15 años, 10 meses
Puntos: 0
Respuesta: Ayuda con Funciones objeto (funtores)

Sí era eso ahora ya se para que sirve nunca me lo explicaron . Muchas gracias CalgaryCorpus

Os dejo el pokemons.txt por si alguien quiere hacer pruebas, ya que buscando por internet no encontré ningún ejemplo sobre funciones objeto:

pokemons.txt
Código:
1	Bulbasaur	2 planta veneno 
2	Ivysaur	2 planta veneno 
3	Venusaur	2 planta veneno 
4	Charmander	1 fuego 
5	Charmeleon	1 fuego 
6	Charizard	2 fuego volador 
7	Squirtle	1 agua 
8	Wartortle	1 agua 
9	Blastoise	1 agua 
10	Caterpie	1 bicho 
11	Metapod	1 bicho 
12	Butterfree	2 bicho volador 
13	Weedle	2 bicho veneno 
14	Kakuna	2 bicho veneno 
15	Beedrill	2 bicho veneno 
16	Pidgey	2 normal volador 
17	Pidgeotto	2 normal volador 
18	Pidgeot	2 normal volador 
19	Rattata	1 normal 
20	Raticate	1 normal 
21	Spearow	2 normal volador 
22	Fearow	2 normal volador 
23	Ekans	1 veneno 
24	Arbok	1 veneno 
25	Pikachu	1 electrico 
26	Raichu	1 electrico 
27	Sandshrew	1 tierra 
28	Sandslash	1 tierra 
29	Nidoran(Female)	1 veneno 
30	Nidorina	1 veneno 
31	Nidoqueen	2 tierra veneno 
32	Nidoran(Male)	1 veneno 
33	Nidorino	1 veneno 
34	Nidoking	2 tierra veneno 
35	Clefairy	1 normal 
36	Clefable	1 normal 
37	Vulpix	1 fuego 
38	Ninetales	1 fuego 
39	Jigglypuff	1 normal 
40	Wigglytuff	1 normal 
41	Zubat	2 veneno volador 
42	Golbat	2 veneno volador 
43	Oddish	2 planta veneno 
44	Gloom	2 planta veneno 
45	Vileplume	2 planta veneno 
46	Paras	2 bicho planta 
47	Parasect	2 bicho planta 
48	Venonat	2 bicho veneno 
49	Venomoth	2 bicho veneno 
50	Diglett	1 tierra 
51	Dugtrio	1 tierra 
52	Meowth	1 normal 
53	Persian	1 normal 
54	Psyduck	1 agua 
55	Golduck	1 agua 
56	Mankey	1 lucha 
57	Primeape	1 lucha 
58	Growlithe	1 fuego 
59	Arcanine	1 fuego 
60	Poliwag	1 agua 
61	Poliwhirl	1 agua 
62	Poliwrath	2 agua lucha 
63	Abra	1 psiquico 
64	Kadabra	1 psiquico 
65	Alkazam	1 psiquico 
66	Machop	1 lucha 
67	Machoke	1 lucha 
68	Machamp	1 lucha 
69	Bellsprout	2 planta veneno 
70	Weepinbell	2 planta veneno 
71	Victreebell	2 planta veneno 
72	Tentacool	2 agua veneno 
73	Tentacruel	2 agua veneno 
74	Geodude	2 roca tierra 
75	Graveler	2 roca tierra 
76	Golem	2 roca tierra 
77	Ponyta	1 fuego 
78	Rapidash	1 fuego 
79	Slowpoke	2 agua psiquico 
80	Slowbro	2 agua psiquico 
81	Magnemite	1 electrico 
82	Magneton	1 electrico 
83	Farfetch'd	2 normal volador 
84	Doduo	2 normal volador 
85	Dodrio	2 normal volador 
86	Seel	1 agua 
87	Dewgong	2 agua hielo 
88	Grimer	1 veneno 
89	Muk	1 veneno 
90	Shellder	1 agua 
91	Cloyster	2 agua hielo 
92	Gastly	2 fantasma veneno 
93	Haunter	2 fantasma veneno 
94	Gengar	2 fantasma veneno 
95	Onix	2 roca tierra 
96	Drowzee	1 psiquico 
97	Hypno	1 psiquico 
98	Krabby	1 agua 
99	Kingler	1 agua 
100	Voltorb	1 electrico 
101	Electrode	1 electrico 
102	Exeggcute	2 planta psiquico 
103	Exeggutor	2 planta psiquico 
104	Cubone	1 tierra 
105	Marowak	1 planta 
106	Hitmonlee	1 lucha 
107	Hitmonchan	1 lucha 
108	Lickitung	1 normal 
109	Koffing	1 veneno 
110	Weezing	1 veneno 
111	Rhyhorn	2 roca tierra 
112	Rhydon	2 roca tierra 
113	Chansey	1 normal 
114	Tangela	1 planta 
115	Kangaskhan	1 normal 
116	Horsea	1 agua 
117	Seadra	1 agua 
118	Goldeen	1 agua 
119	Seaking	1 agua 
120	Staryu	1 agua 
121	Starmie	2 agua psiquico 
122	Mr.Mime	1 psiquico 
123	Scyther	2 bicho volador 
124	Jynx	2 hielo psiquico 
125	Electabuzz	1 electrico 
126	Magmar	1 fuego 
127	Pinsir	1 bicho 
128	Tauros	1 normal 
129	Magikarp	1 agua 
130	Gyrados	2 agua volador 
131	Lapras	2 agua hielo 
132	Ditto	1 normal 
133	Eevee	1 normal 
134	Vaporeon	1 agua 
135	Jolteon	1 electrico 
136	Flareon	1 fuego 
137	Porygon	1 normal 
138	Omanyte	2 agua roca 
139	Omastar	2 agua roca 
140	Kabuto	2 agua roca 
141	Kabutops	2 agua roca 
142	Aerodactyl	2 roca volador 
143	Snorlax	1 normal 
144	Articuno	2 hielo volador 
145	Zapdos	2 electrico volador 
146	Moltres	2 fuego volador 
147	Dratini	1 dragon 
148	Dragonair	1 dragon 
149	Dragonite	2 dragon volador 
150	Mewtwo	1 psiquico 
151	Mew	1 nuevo 
152	Chikorita	1 planta 
153	Bayleef	1 planta 
154	Meganium	1 planta 
155	Cyndaquil	1 fuego 
156	Quilava	1 fuego 
157	Typhlosion	1 fuego 
158	Totodile	1 agua 
159	Croconaw	1 agua 
160	Feraligatr	1 agua 
161	Sentret	1 normal 
162	Furret	1 normal 
163	HootHoot	2 normal volador 
164	Noctowl	2 normal volador 
165	Ledyba	2 bicho volador 
166	Ledian	2 bicho volador 
167	Spinarak	2 bicho veneno 
168	Ariados	2 bicho veneno 
169	Crobat	2 veneno volador 
170	Chinchou	2 agua electrico 
171	Lanturn	2 agua electrico 
172	Pichu	1 electrico 
173	Cleffa	1 normal 
174	Igglybuff	1 normal 
175	Togepi	1 normal 
176	Togetic	2 normal volador 
177	Natu	2 psiquico volador 
178	Xatu	2 psiquico volador 
179	Mareep	1 electrico 
180	Flaaffy	1 electrico 
181	Ampharos	1 electrico 
182	Bellossom	1 planta 
183	Marill	1 agua 
184	Azumarill	1 agua 
185	Sudowoodo	1 roca 
186	Politoed	1 agua 
187	Hoppip	2 planta volador 
188	Skiploom	2 planta volador 
189	Jumpluff	2 planta volador 
190	Aipom	1 normal 
191	Sunkern	1 planta 
192	Sunflora	1 planta 
193	Yanma	2 bicho volador 
194	Wooper	2 agua tierra 
195	Quagsire	2 agua tierra 
196	Espeon	1 psiquico 
197	Umbreon	1 demonio 
198	Murkrow	2 demonio volador 
199	Slowking	2 agua psiquico 
200	Misdreavus	1 fantasma 
201	Unown	1 psiquico 
202	Wobbuffet	1 psiquico 
203	Girafarig	2 normal psiquico 
204	Pineco	1 bicho 
205	Forretress	2 acero bicho 
206	Dunsparce	1 normal 
207	Gligar	2 tierra volador 
208	Steelix	2 acero planta 
209	Snubbull	1 normal 
210	Granbull	1 normal 
211	Qwilfish	2 agua veneno 
212	Scizor	2 acero bicho 
213	Shuckle	2 bicho roca 
214	Heracross	2 bicho lucha 
215	Sneasel	2 demonio hielo 
216	Teddiursa	1 normal 
217	Ursaring	1 normal 
218	Slugma	2 fuego roca 
219	Magcargo	2 fuego roca 
220	Swinub	2 hielo tierra 
221	Piloswine	2 hielo tierra 
222	Corsola	2 agua roca 
223	Remoraid	1 agua 
224	Octillery	1 agua 
225	Delibird	2 hielo volador 
226	Mantine	2 agua volador 
227	Skarmory	2 acero volador 
228	Houndour	2 demonio fuego 
229	Houndoom	2 demonio fuego 
230	Kingdra	2 agua dragon 
231	Phanpy	1 tierra 
232	Donphan	1 tierra 
233	Porygon2	1 normal 
234	Stantler	1 normal 
235	Smeargle	1 normal 
236	Tyrogue	1 lucha 
237	Hitmontop	1 lucha 
238	Smoochum	2 hielo psiquico 
239	Elekid	1 electrico 
240	Magby	1 fuego 
241	Miltank	1 normal 
242	Blissey	1 normal 
243	Raikou	1 electrico 
244	Entei	1 fuego 
245	Suicune	1 agua 
246	Larvitar	2 roca tierra 
247	Pupitar	2 roca tierra 
248	Tyranitar	2 demonio roca 
249	Lugia	2 psiquico volador 
250	Ho-Oh	2 fuego volador 
251	Celebi	2 planta psiquico
  #15 (permalink)  
Antiguo 16/06/2008, 03:36
 
Fecha de Ingreso: junio-2008
Mensajes: 10
Antigüedad: 15 años, 10 meses
Puntos: 0
Respuesta: Ayuda con Funciones objeto (funtores)

Bueno ya está todo perfect, aquí teneis un main para comprobar las funciones del pokedex:

Código:
#include <pokemon.h>
#include <pokedex.h>
#include <fstream>

using namespace std;

int main() {
	// Inicializacion
	pokedex pok;
	ifstream in,in1,in2;
	in.open("pokemons.txt");
	in>>pok;
	// Probando totales() y deTipo()
	map<string,int> auxmap=pok.totales();
	vector<pokemon> auxvec=pok.deTipo("planta");
	ostream_iterator<pokemon> itr_out1(cout,"\n");
	cout<<"Muestra los "<<auxmap["planta"]<<" pokemons de tipo planta:"<<endl;
	copy(auxvec.begin(),auxvec.end(),itr_out1);
	// Probando info()
	cout<<"\nAhora intentamos buscar un pokemon <Pikachu>, si existe se muestra"<<endl;
	pokemon pokemon1=pok.info("Pikachu");
	cout<<pokemon1<<endl;
	// Probando tipos()
	cout<<"\nTipos de pokemon en el pokedex por orden alfabetico:";
	ostream_iterator<string> itr_out2(cout,"\n");
	set<string> tipos1=pok.tipos();
	copy(tipos1.begin(),tipos1.end(),itr_out2);
	// Probando fusion()
	pokedex pok1,pok2;
	in1.open("pokemons1.txt");
	in1>>pok1;
	in2.open("pokemons2.txt");
	in2>>pok2;
	cout<<"\nPokedex1 antes de la fusion:"<<endl;
	cout<<pok1;
	cout<<"Pokedex2 antes de la fusion:"<<endl;
	cout<<pok2;
	cout<<"Pokedex1 se fusiona con Pokedex2, y saco por salida Pokedex1:"<<endl;
	pok1.fusion(pok2);
	cout<<pok1;
	return 0;
}
pokemons1.txt
Cita:
1 Bulbasaur 2 planta veneno
2 Ivysaur 2 planta veneno
3 Venusaur 2 planta veneno
4 Charmander 1 fuego
pokemons2.txt
Cita:
4 Charmander 1 fuego
5 Charmeleon 1 fuego
6 Charizard 2 fuego volador
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 07:09.