std::list<mit eigenem typ> und find() aufrufen mit eigener parameterfunktion



  • ich habe folgendes
    eine Klasse

    class Entry
    {
    public:
    	Entry(const string&, const string& , const string&, const string& );
    	//Entry(const Entry& src); //copyconstruct.
    
    	bool operator<(const Entry& value) const;
    	bool operator>(const Entry& value) const
    	{
    		return value < *this;
    	}
    	virtual ~Entry(void);
    
    	string getVorname()const;
    	string getNachname()const;
    	string getGebaeude()const;
    	string getTelefonnummer()const;
    
    	void setVorname(string& vorn);
    	void setNachname(string& nach);
    	void setGeb(string& geb);
    	void setTel(string& tel);
    
    private:
    	string vorname;
    	string nachname;
    	string gebaeude;
    	string telefonnummer;
    	string makeCompareable(const string& str) const;
    };
    
    inline ostream& operator<<( ostream& out,  Entry const &t ) 
    { 
    	out <<" \nName:\t\t"<<t.getNachname()
    		<<" \nVorname:\t"<<t.getVorname()
    		<<" \nGebaeude:\t"<<t.getGebaeude()
    		<<" \nTelefonnummer:\t"<<t.getTelefonnummer()
    		<<"\n******************************"<<endl;
    	return out; 
    }
    

    und in meiner main habe ich eine txtDatei(name vorname raum tele) eingelesen in das obengenannte objekt mit der std::list abgespeichert.
    jetzt möchte ich in meiner switchanweisung eine inverse suche machen, d.h.
    ich suche nach der telefonnummer und ausgegeben wird der zugehörige datensatz

    ich habe zwar ein ahnung als lösung aber finde das blöd gelöst. es gibt doch die find() funktion nur weiss ich nicht wie das geht..

    ich habe also eingelesen in struktur // hier verkürzt dargestellt.

    std::list<Entry> Telefonliste;
    	Entry *pEntry=NULL;
    
    ifstream infile("Daten.txt", ios::in);
    if(!infile)
    {
    	cerr<<"File could not be opened"<<endl;				exit(1);
    }
    string vname, nname, geb, tel;
    
    while(!infile.eof())
    {
    getline(infile, nname,' ');
    getline(infile, vname,' ');
    getline(infile, geb,' ');
    getline(infile, tel,'\n');
    pEntry= new Entry(nname,vname,geb,tel);
    Telefonliste.push_back(*pEntry);
    }
    cout<<"Daten wurden in Datenstruktur eingelesen\n";
    

    ausgabe funktioniert , dh. die einzelnen daten sind in das objekt und die objekte in der liste.

    jetzt möchte ich die inverse suche starten habe : allerdings happerts noch mit der umsetzung..

    if(!Telefonliste.empty())
    {
    	string tele;
    	cout<<" Inverse Suche, Telefonnummer eingeben: ";
    	getline(cin, tele);
    	std::list<Entry>::iterator location;
    	location= std::find(Telefonliste.begin(),Telefonliste.begin(), ???? wie welche suchparameter); 
    // location->gettelefonnummer==tele oder wie? aber gibt mir dann fehler aus
    //operatorfehler , was fehlt, hmmm eventuell einen überladenen ==operator? 
    //habe da auch einiges probiert aber nicht hinbekommen, oder einfach eine //vergleichsfunktion nur das wie ist mir noch unbekannt.
    // habe mir zwar grade das	
    /*std::list<Entry>::const_iterator iter; 
    	for(iter=Telefonliste.begin(); iter!=Telefonliste.end(); ++iter) 
    		{ 
    		 if (iter->getTelefonnummer()==tele)
    		cout<<*iter;			  
    		} */....überlegt aber finde ich umständlich..
    }else
    	{
    	cout<<" Telefonliste leer, zuerst einlesen!\n";
    	}
    

    sodele
    also gibt es nicht irgendwie sowas

    location= std::find(Telefonliste.begin(),Telefonliste.begin(), ???? wie welche suchparameter);
    

    ich benötige also wieder eure hilfe , und bin wie immer dankbar für jeden tip.



  • Hallo,

    Bastel dir dafü einen Funktor. Etwa so

    struct FindTeleNr : public std::unary_function<Entry,bool>
    {
        std::string tele;
        FindTeleNr(const std::string& suchtele) { tele = suchtele; }
        bool operator()(const Entry & object)
        {
             return object.telefonnummer == tele;
        }
    };
    // Aufruf dann so
    location= std::find(Telefonliste.begin(),Telefonliste.begin(), FindTeleNr(tele));
    


  • Braunstein schrieb:

    Hallo,

    Bastel dir dafü einen Funktor. Etwa so

    struct FindTeleNr : public std::unary_function<Entry,bool>
    {
        std::string tele;
        FindTeleNr(const std::string& suchtele) { tele = suchtele; }
        bool operator()(const Entry & object)
        {
             return object.telefonnummer == tele;
        }
    };
    // Aufruf dann so
    location= std::find(Telefonliste.begin(),Telefonliste.begin(), FindTeleNr(tele));
    

    ok leuchtet mir ein jedoch hab ich nun folgendes

    error C2784: "bool std::operator ==(const std::list<_Ty,_Ax> &,const std::list<_Ty,_Ax> &)": template-Argument für "const std::list<_Ty,_Ax> &" konnte nicht von "Entry" hergeleitet werden.
            c:\programme\microsoft visual studio 8\vc\include\list(1264): Siehe Deklaration von 'std::operator =='
            c:\programme\microsoft visual studio 8\vc\include\algorithm(74): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "_InIt std::_Find<std::list<_Ty>::_Iterator<_Secure_validation>,FindTeleNr>(_InIt,_InIt,const FindTeleNr &)".
            with
            [
                _InIt=std::list<Entry>::_Iterator<false>,
                _Ty=Entry,
                _Secure_validation=false
            ]
            e:\fbi\weber\pk\loesungen\klss05\klss05.cpp(122): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "_InIt std::find<std::list<_Ty>::_Iterator<_Secure_validation>,FindTeleNr>(_InIt,_InIt,const FindTeleNr &)".
            with
            [
                _InIt=std::list<Entry>::_Iterator<true>,
                _Ty=Entry,
                _Secure_validation=true
            ]
    c:\programme\microsoft visual studio 8\vc\include\algorithm(40) : error C2784: "bool std::operator ==(const std::istream_iterator<_Ty,_Elem,_Traits,_Diff> &,const std::istream_iterator<_Ty,_Elem,_Traits,_Diff> &)": template-Argument für "const std::istream_iterator<_Ty,_Elem,_Traits,_Diff> &" konnte nicht von "Entry" hergeleitet werden.
            c:\programme\microsoft visual studio 8\vc\include\iterator(266): Siehe Deklaration von 'std::operator =='
    c:\programme\microsoft visual studio 8\vc\include\algorithm(40) : error C2784: "bool std::operator ==(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)": template-Argument für "const std::basic_string<_Elem,_Traits,_Alloc> &" konnte nicht von "Entry" hergeleitet werden.
            c:\programme\microsoft visual studio 8\vc\include\string(91): Siehe Deklaration von 'std::operator =='
    c:\programme\microsoft visual studio 8\vc\include\algorithm(40) : error C2784: "bool std::operator ==(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)": template-Argument für "const _Elem *" konnte nicht von "Entry" hergeleitet werden.
            c:\programme\microsoft visual studio 8\vc\include\string(81): Siehe Deklaration von 'std::operator =='
    c:\programme\microsoft visual studio 8\vc\include\algorithm(40) : error C2784: "bool std::operator ==(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)": template-Argument für "const std::basic_string<_Elem,_Traits,_Alloc> &" konnte nicht von "Entry" hergeleitet werden.
            c:\programme\microsoft visual studio 8\vc\include\string(71): Siehe Deklaration von 'std::operator =='
    c:\programme\microsoft visual studio 8\vc\include\algorithm(40) : error C2784: "bool std::operator ==(const std::allocator<_Ty> &,const std::allocator<_Other> &) throw()": template-Argument für "const std::allocator<_Ty> &" konnte nicht von "Entry" hergeleitet werden.
            c:\programme\microsoft visual studio 8\vc\include\xmemory(174): Siehe Deklaration von 'std::operator =='
    c:\programme\microsoft visual studio 8\vc\include\algorithm(40) : error C2784: "bool std::operator ==(const std::istreambuf_iterator<_Elem,_Traits> &,const std::istreambuf_iterator<_Elem,_Traits> &)": template-Argument für "const std::istreambuf_iterator<_Elem,_Traits> &" konnte nicht von "Entry" hergeleitet werden.
            c:\programme\microsoft visual studio 8\vc\include\xutility(2181): Siehe Deklaration von 'std::operator =='
    c:\programme\microsoft visual studio 8\vc\include\algorithm(40) : error C2784: "bool std::operator ==(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)": template-Argument für "const std::reverse_iterator<_RanIt> &" konnte nicht von "Entry" hergeleitet werden.
            c:\programme\microsoft visual studio 8\vc\include\xutility(1864): Siehe Deklaration von 'std::operator =='
    c:\programme\microsoft visual studio 8\vc\include\algorithm(40) : error C2784: "bool std::operator ==(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)": template-Argument für "const std::pair<_Ty1,_Ty2> &" konnte nicht von "Entry" hergeleitet werden.
            c:\programme\microsoft visual studio 8\vc\include\utility(60): Siehe Deklaration von 'std::operator =='
    c:\programme\microsoft visual studio 8\vc\include\algorithm(40) : error C2676: Binärer Operator '==': 'Entry' definiert diesen Operator oder eine Konvertierung in einen für den vordefinierten Operator geeigneten Typ nicht
    

    hab zwar ein operator versucht zu basteln mit

    bool operator==(const Entry& value) const
    {
    return (value.telefonnummer==telefonnummer);
    }
    aber leider ohne wirkung 😞



  • Du benötigst std::find_if statt std::find ; und im Prädikat muss es natürlich return object.getTelefonnummer() == tele; heißen.

    Die Rückgabewerte der Getter kannst du im übrigen auch zu std::string const& ändern.



  • Du mußt statt find hier find_if verwenden. Sorry, war mein Fehler.
    [edit]Viel zu spät. 🙂 [edit]



  • finix schrieb:

    Du benötigst std::find_if statt std::find ; und im Prädikat muss es natürlich return object.getTelefonnummer() == tele; heißen.

    Die Rückgabewerte der Getter kannst du im übrigen auch zu std::string const& ändern.

    ok dankeee das mit dem getTelefonummer() hatte ich endeckt (wg telefonnummer is privat) aber find_if nicht 🙂

    ps. falls jemand das liest blos nicht sicherheitsabfrage vergessen
    if(location!= Telefonliste.end()) // sonst referenziert der ins nichts undgibt runtimefehler
    cout<<*location;

    danke nochmal an die fleissigen Helfer *freu* 😃



  • allerdings frag ich mich nun doch was performanter und einfacher ist?

    das hier

    bool found=false;
    					 std::list<Entry>::const_iterator iter; 
    					 for(iter=Telefonliste.begin(); iter!=Telefonliste.end(); ++iter) 
    						{ 
    							if (iter->getTelefonnummer()==tele)
    							{
    								cout<<*iter;
    								found=true;
    							}
    						} 
    					  if (found==false)
    						  cout<<" Telefonnummer nicht enthalten! ";
    

    oder die obige lösung hmmm? hehe



  • Ich denke mal find-if wird intern auch nichts anderes machen. Ansonsten probiers halt aus.


Anmelden zum Antworten