Chars zusammenfügen und sortieren



  • 1. Welches meinst du? Du hast zwei:

    for( deque< Entry >::iterator e = fx_Entries.begin();
    

    und:

    for( Entry e; fx_fwpNavFIX >> e; )
    

    Und bei beiden steht der Typ. 😉

    2. Fast. Das ist ein Iterator:
    enweder so:

    (*e).m_Fix
    

    oder:

    e->m_Fix
    


  • campinge schrieb:

    3. In der Ursrungsdatei gibt es einige Header-Zeilen, die mit einem ';' beginnen. Wie kann ich die ausschließen? -- Selbiges für die Vergleichsdatei, nur mit '/'

    Du kannst prüfen, ob das erste Zeichen ein solches ist, wenn ja, überspringst du die Zeile (d.h. du liest sie z.B. mit std::getline() , aber speicherst sie nirgends).



  • campinge schrieb:

    3. In der Ursrungsdatei gibt es einige Header-Zeilen, die mit einem ';' beginnen. Wie kann ich die ausschließen? -- Selbiges für die Vergleichsdatei, nur mit '/'

    Du kannst vor jedem Einlesen eines Eintrags prüfen ob ein ';' vorangestellt ist und falls ja die Zeile ignorieren.

    Eine Möglichkeit, dies zu integrieren, besteht darin, die Einlese-Routine von Entry zu erweitern:

    std::istream& operator>>( std::istream& in, Entry& e ) // Lesen
    {   //  prüfe zunächst auf Kommentarzeilen und 
        // lese 'fix', ignoriere 6 Zeichen, lese 'latitude' und 'longitude'
        while( in >> std::ws && !in.eof() && char(in.peek()) == ';' )  // solange ein ';' folgt ..
            in.ignore( 9999, '\n' );                                   // ..überlese bis Zeilenende
        return (in >> e.m_fix).ignore( 6 ) >> e.m_latitude >> e.m_longitude;
    }
    

    Zur Erklärung. Das in >> std::ws überliest zunächst alle white space Zeichen (ws). Dies ist notwendig, da peek wirklich nur das nächste Zeichen anschaut und dies könnte ja auch ein Leerzeichen oder Zeilenende sein, aber diese interessieren ja nicht. Die Prüfung auf !in.eof() sorgt dann dafür, dass peek nicht mit EOF (d.h. End Of File) aufgerufen wird, da es sonst ein EOF zurückgibt und der cast nach char nicht sauber wäre. Und schließlich wird mit in.peek() das nächste Zeichen angesehen - OHNE es zu lesen! D.h. es fehlt kein Zeichen beim nächsten Einlesen in 'in >> e.m_fix', falls es kein ';' war und die while-Schleife beendet wurde.

    Die zweite Möglichkeit besteht darin, das 'Kommentar überlesen' in einen sogenannten Manipulator zu packen und diesen dann aufzurufen. Der sieht so aus:

    std::istream& comment( std::istream& in ) // überliest Kommentar beginnend mit ';'
    {
        while( in >> std::ws && !in.eof() && char(in.peek()) == ';' )
            in.ignore( 999, '\n' );
        return in;
    }
    

    und könnte dann so in Zeile 55 Deines Programms integriert werden

    for( Entry e; fx_fwpNavFIX >> comment >> e; )   // (55) Einträge von Entry durchlaufen
        {
            fx_Entries.push_back( e );  // e in fx_Entries einfügen
        }
    

    Gruß
    Werner



  • Hey, vielen Dank!

    Ich habs doch tatsächlich noch geschafft das Programm zum laufen zu bringen.
    -Allerdings nicht so, wie geplant...

    Irgendwie scheint das Einlesen nicht so richtig zu funktionieren. Es wird der Erste wegpunkt eingelesen und dann wars das auch schon, der Rest bleibt 'quasi' leer. Die letzte Schleife wird aufgerufen, aber direkt beendet. Auch Testausgaben innerhalbder Schleifen wurden übersprungen. Jetzt bin ich total verwirrt...

    Ich stelle euch hier mal ein paar Auszüge aus den Dateien rein und den Programmcode. Es wäre super, wenn das einer von euch mal durch den compiler jagen könnte um herauszufinden was da genau schief geht...

    "navdata/wpNavFIX.txt"

    ;Commentlinie
    SPOLE                   SPOLE-90.000000   0.000000
    89W80                   89W80-89.000000-180.000000
    89W79                   89W79-89.000000-179.000000
    89W78                   89W78-89.000000-178.000000
    89W77                   89W77-89.000000-177.000000
    89W76                   89W76-89.000000-176.000000
    89W75                   89W75-89.000000-175.000000
    89W74                   89W74-89.000000-174.000000
    89W73                   89W73-89.000000-173.000000
    89W72                   89W72-89.000000-172.000000
    89W71                   89W71-89.000000-171.000000
    89W70                   89W70-89.000000-170.000000
    

    "navigation/Fixes.db"

    //commentline
    00MKK;22.528056;-156.170961;3
    00UPP;20.566668;-154.125;3
    03MCT;55.136667;-7.191389;1
    03SML;25.61;30.635278;3
    04THT;73.147778;-68.683056;3
    06TRA;47.733334;8.283334;4
    08YBK;63.751277;-100.000685;3
    15SNT;40;-16;3
    16DEL;30.840107;-105.380861;1
    16YYQ;60.77426;-99.999245;1
    17AST;26.330833;29.001667;3
    1F;47.630556;-65.744722;2
    21YQL;49.00746;-109.73596;1
    21YZS;61.566959;-89.049881;2
    22SNT;45;-14;3
    247PQ;33.75;165;3
    24DUB;55.0875;-8.569722;1
    24VLS;-15.186667;28.825556;2
    251PQ;35.535231;149.995961;3
    25VLS;-15.616944;28.107778;3
    27VLS;-14.973056;28.7075;3
    

    Programm:

    #include <algorithm> // sort
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <deque> 
    
    struct Entry	// Struktur für das Eingangsfile
    {
        bool operator<( const Entry& b ) const	// legt die Reihenfolge bei 'sort' fest
        {
            return m_fix < b.m_fix;
        }
        std::string m_fix;			// String für das Fix
        double m_latitude;			// bool für Latitude
        double m_longitude;			// bool für longlitude
    }; 
    
    struct Compare	// Strukur für das Vergleichsfile
    {
        bool operator<( const Compare& b ) const	// legt die Reihenfolge bei 'sort' fest
        {
            return m_fix < b.m_fix;
        }
        std::string m_fix;			// String für das Fix
        double m_latitude;			// bool für latitude
        double m_longitude;			// bool für longlitude
    	int m_Number;				// int für die nummer
    }; 
    
    std::istream& operator>>( std::istream& in, Entry& e ) // Lesen
    {   // lese 'fix', ignoriere 6 Zeichen, lese 'latitude' und 'longitude'
        return (in >> e.m_fix).ignore( 6 ) >> e.m_latitude >> e.m_longitude;
    }
    std::ostream& operator<<( std::ostream& out, const Entry e ) // Formatieren
    {   // Ausgabe im neuen Format
        // z.B.: ENTRE;-31.534170;130.949200
        return out << e.m_fix << ';' << e.m_latitude << ';' << e.m_longitude;
    }
    std::istream& operator>>( std::istream& in, Compare& f ) // Lesen
    {   // lese 'fix', 'latitude', 'longitude' und 'fix'
    	return in >> f.m_fix >> f.m_latitude >> f.m_longitude >> f.m_fix;
    }
    std::istream& comment( std::istream& in ) // überliest Kommentar beginnend mit ';'
    {
        while( in >> std::ws && !in.eof() && char(in.peek()) == ';' )
            in.ignore( 999, '\n' );
        return in;
    }
    std::istream& comment2( std::istream& in ) // überliest Kommentar beginnend mit ';'
    {
        while( in >> std::ws && !in.eof() && char(in.peek()) == '/' )
            in.ignore( 999, '\n' );
        return in;
    }
    
    int ExportFixes()
    {
        using namespace std;
        deque< Entry > fx_Entries;													// Container mit Struktur "Entry" erstellen
    	deque< Compare > fx_Compare;
    	std::ifstream fx_fwpNavFIX("navdata/wpNavFIX.txt");							// Input- Datei wpNavFix definieren
    	std::ifstream fx_fFixes("navigation/Fixes.db");								// Input-Datei Fixes definieren
        for(Entry e; fx_fwpNavFIX >> comment >> e; )								// Einträge von Entry durchlaufen
        {
            fx_Entries.push_back( e );												// e in fx_Entries einfügen
        }
    	for( Compare f; fx_fFixes >> comment2 >> f; )								// Einträge von Entry durchlaufen
    	{
    		fx_Compare.push_back( f );
    	}
        sort( fx_Entries.begin(), fx_Entries.end() );								// fx_Entries sortieren
        ofstream fx_OutFile("navigation_new/Fixes.db");								// Ausgabedatei definieren
        for( deque< Entry >::iterator e = fx_Entries.begin(); e != fx_Entries.end(); ++e ) //fx_Entries durchlaufen
        {
    		for( deque< Compare >::iterator f = fx_Compare.begin(); f != fx_Compare.end(); ++f ) //fx_Compare durchlaufen
    		{
    			if ( e->m_fix == f->m_fix && e->m_fix[0] != ';' )						// wenn Eintrag gefunden
    			{
    				fx_OutFile << *e << ';' << f->m_Number << endl;					// Schreibe in Datei
    			}
    			else if ( f ==  fx_Compare.end() )				// Wenn Fileend
    			{
    				fx_OutFile << *e << ';' << '5' << endl;							// 5 dranhängen
    			}
    		}
        }
        return (true);
    }
    


  • campinge schrieb:

    Irgendwie scheint das Einlesen nicht so richtig zu funktionieren. Es wird der Erste wegpunkt eingelesen und dann wars das auch schon, der Rest bleibt 'quasi' leer. ...

    Beim Einlesen ist das Format der einzulesenden Datei das A und O. Es dauert immer ein wenig, bis man es aus den Leuten herausbekommen hat 😉

    Du schriebst am 11.1.:

    campinge schrieb:

    die Datei sieht in etwa so aus:

    `ENTRE ENTRE-31.534170 130.949200

    PEA83 PEA83-31.533961 115.952714

    89W80 89W80-89.000000-180.000000

    `

    und jetzt:

    campinge schrieb:

    "navdata/wpNavFIX.txt"

    ;Commentlinie
    SPOLE                   SPOLE-90.000000   0.000000
    89W80                   89W80-89.000000-180.000000
    89W79                   89W79-89.000000-179.000000
    89W78                   89W78-89.000000-178.000000
    

    ist das gleiche, sieht aber anders aus 🙄

    Ich habe Die Einlesefunktion von 'Entry' noch mal geändert, so dass sie mit beliebig vielen white space Zeichen zwischen den ersten beiden (Fix-)Worten zurechtkommt.

    Das gleiche gilt für das Format der Compare-Datei.

    campinge schrieb:

    std::istream& operator>>( std::istream& in, Compare& f ) // Lesen
    {   // lese 'fix', 'latitude', 'longitude' und 'fix'
    	return in >> f.m_fix >> f.m_latitude >> f.m_longitude >> f.m_fix;
    }
    

    aber:

    campinge schrieb:

    "navigation/Fixes.db"

    //commentline
    00MKK;22.528056;-156.170961;3
    00UPP;20.566668;-154.125;3
    03MCT;55.136667;-7.191389;1
    

    also ist der Kommentar oben glatt gelogen 😉 - korrekt wäre:

    {   // lese 'fix' bis';', 'latitude', ';', 'longitude', ';' und 'nummer'
    

    Ich habe beides angepasst, ein wenig umstrukturiert, damit es nicht so durcheinander erscheint und noch den find-Algorithmus von C++ eingebaut.

    #include <algorithm> // sort, find
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <deque>
    
    // --   Helferlein zum Einlesen eines erwarteten Zeichens
    template< char C >  
    std::istream& Char( std::istream& in )
    {
        char c;
        if( in >> c && c != C )
            in.setstate( std::ios_base::failbit );
        return in;
    }
    
    struct Entry    // Struktur für das Eingangsfile
    {
        bool operator<( const Entry& b ) const    // legt die Reihenfolge bei 'sort' fest
        {
            return m_fix < b.m_fix;
        }
        std::string m_fix;            // String für das Fix
        double m_latitude;            // bool für Latitude
        double m_longitude;            // bool für longlitude
    };
    
    struct Compare    // Strukur für das Vergleichsfile
    {
        explicit Compare( const std::string& fix = std::string() )  // Konstruktor für Vergleiche
            : m_fix( fix )
            , m_latitude(), m_longitude()
            , m_Number()
        {}
        bool operator<( const Compare& b ) const    // legt die Reihenfolge bei 'sort' fest
        {
            return m_fix < b.m_fix;
        }
        bool operator==( const Compare& b ) const
        {
            return m_fix == b.m_fix;
        }
        std::string m_fix;            // String für das Fix
        double m_latitude;            // bool für latitude
        double m_longitude;            // bool für longlitude
        int m_Number;                // int für die nummer
    };
    bool operator!=( const Compare& a, const Compare& b )
    {
        return !(a == b);
    }
    
    std::istream& operator>>( std::istream& in, Entry& e ) // Lesen
    {   // lese 'fix', ab nächsten char 5 Zeichen ignorieren, lese 'latitude' und 'longitude'
        return (in >> e.m_fix >> std::ws).ignore( 5 ) >> e.m_latitude >> e.m_longitude;
    }
    std::ostream& operator<<( std::ostream& out, const Entry e ) // Formatieren
    {   // Ausgabe im neuen Format
        // z.B.: ENTRE;-31.534170;130.949200
        return out << e.m_fix << ';' << e.m_latitude << ';' << e.m_longitude;
    }
    std::istream& operator>>( std::istream& in, Compare& f ) // Lesen
    {   // lese 'fix' bis';', 'latitude', ';', 'longitude', ';' und 'nummer'
        // z.B.: 00MKK;22.528056;-156.170961;3
        return std::getline( in, f.m_fix, ';' ) >> f.m_latitude >> Char<';'> >> f.m_longitude >> Char<';'> >> f.m_Number;
    }
    std::istream& comment( std::istream& in ) // überliest Kommentar beginnend mit ';'
    {
        while( in >> std::ws && !in.eof() && char(in.peek()) == ';' )
            in.ignore( 999, '\n' );
        return in;
    }
    std::istream& comment2( std::istream& in ) // überliest Kommentar beginnend mit '/'
    {
        while( in >> std::ws && !in.eof() && char(in.peek()) == '/' )
            in.ignore( 999, '\n' );
        return in;
    }
    
    int ExportFixes()
    {
        using namespace std;
        deque< Entry > fx_Entries;                                      // Container mit Struktur "Entry" erstellen
        {
            std::ifstream fx_fwpNavFIX("navdata/wpNavFIX.txt");         // Input- Datei wpNavFix definieren
            for(Entry e; fx_fwpNavFIX >> comment >> e; )                // Einträge von Entry durchlaufen
            {
                fx_Entries.push_back( e );                              // e in fx_Entries einfügen
            }
            sort( fx_Entries.begin(), fx_Entries.end() );               // fx_Entries sortieren
        }
    
        deque< Compare > fx_Compare;
        {
            std::ifstream fx_fFixes("navigation/Fixes.db");             // Input-Datei Fixes definieren
            for( Compare f; fx_fFixes >> comment2 >> f; )               // Einträge von Entry durchlaufen
            {
                fx_Compare.push_back( f );
            }
        }
        ofstream fx_OutFile("navigation_new/Fixes.db");                                // Ausgabedatei definieren
        for( deque< Entry >::iterator e = fx_Entries.begin(); e != fx_Entries.end(); ++e ) //fx_Entries durchlaufen
        {
            // --   alle Einträge aus 'navdata/wpNavFIX.txt' sortiert wegschreiben
            //      hinter jeden Eintrag wird die Zahl geschrieben, die in 'navigation_new/Fixes.db' für diesen Eintrag
            //      gefunden wurde. Falls keiner gefunden wurde, so wird eine '5' angehängt.
            fx_OutFile << *e << ';';
            deque< Compare >::iterator f = find( fx_Compare.begin(), fx_Compare.end(), Compare( e->m_fix ) );
            if( f != fx_Compare.end() )
                fx_OutFile << f->m_Number;      // Nummer aus 'navigation_new/Fixes.db' für diesen Eintrag anhängen
            else
                fx_OutFile << '5';              // default ist 5
            fx_OutFile << endl;
        }
        return (true);
    }
    

    bei mir funktioniert das jetzt 🕶
    .. und nun sag' uns bitte noch wie viel Zeit die Datei mit den 200000 Zeilen benötigt.

    Gruß
    Werner



  • wow, super!

    Ich hatte heute Anbend noch Zeit es zu testen und habe noch schnell einen Timer drumherum gebastelt. für 188301 Zeilen habe ich auf meinem Laptop 2:26:11 Stunden gebracht, Die Zeit hat sich also fast um die Hälfte verkürzt. Vielen Dank nochmal!

    Jetzt muss ich die Vorlage nur noch ein paar mal umbasteln für die ganzen anderen Dateien, dann sollte das Programm komplett laufen.

    Super Support, jungs!



  • campinge schrieb:

    für 188301 Zeilen habe ich auf meinem Laptop 2:26:11 Stunden gebraucht

    Im Release-Mode? O.o

    bb



  • @Werner Salomon: 👍

    und jetzt, wo der code aufgeräumt ist,
    mir scheint, man könnte fx_Compare nach dem einlesen sortieren und dann statt find lieber lower_bound nehmen. müßte den lauf eigentlich vom stundenbereich in den sekundenbereich drücken.

    ich hab fast nix geändert und es auch nicht getestet. so diese richtung meine ich:

    #include <algorithm> // sort, find
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <deque>
    
    // --   Helferlein zum Einlesen eines erwarteten Zeichens
    template< char C >  
    std::istream& Char( std::istream& in )
    {
        char c;
        if( in >> c && c != C )
            in.setstate( std::ios_base::failbit );
        return in;
    }
    
    struct Entry    // Struktur für das Eingangsfile
    {
        bool operator<( const Entry& b ) const    // legt die Reihenfolge bei 'sort' fest
        {
            return m_fix < b.m_fix;
        }
        std::string m_fix;            // String für das Fix
        double m_latitude;            // bool für Latitude
        double m_longitude;            // bool für longlitude
    };
    
    struct Compare    // Strukur für das Vergleichsfile
    {
        explicit Compare( const std::string& fix = std::string() )  // Konstruktor für Vergleiche
            : m_fix( fix )
            , m_latitude(), m_longitude()
            , m_Number()
        {}
        bool operator<( const Compare& b ) const    // legt die Reihenfolge bei 'sort' fest
        {
            return m_fix < b.m_fix;
        }
        bool operator==( const Compare& b ) const
        {
            return m_fix == b.m_fix;
        }
        std::string m_fix;            // String für das Fix
        double m_latitude;            // bool für latitude
        double m_longitude;            // bool für longlitude
        int m_Number;                // int für die nummer
    };
    bool operator!=( const Compare& a, const Compare& b )
    {
        return !(a == b);
    }
    
    std::istream& operator>>( std::istream& in, Entry& e ) // Lesen
    {   // lese 'fix', ab nächsten char 5 Zeichen ignorieren, lese 'latitude' und 'longitude'
        return (in >> e.m_fix >> std::ws).ignore( 5 ) >> e.m_latitude >> e.m_longitude;
    }
    std::ostream& operator<<( std::ostream& out, const Entry e ) // Formatieren
    {   // Ausgabe im neuen Format
        // z.B.: ENTRE;-31.534170;130.949200
        return out << e.m_fix << ';' << e.m_latitude << ';' << e.m_longitude;
    }
    std::istream& operator>>( std::istream& in, Compare& f ) // Lesen
    {   // lese 'fix' bis';', 'latitude', ';', 'longitude', ';' und 'nummer'
        // z.B.: 00MKK;22.528056;-156.170961;3
        return std::getline( in, f.m_fix, ';' ) >> f.m_latitude >> Char<';'> >> f.m_longitude >> Char<';'> >> f.m_Number;
    }
    std::istream& comment( std::istream& in ) // überliest Kommentar beginnend mit ';'
    {
        while( in >> std::ws && !in.eof() && char(in.peek()) == ';' )
            in.ignore( 999, '\n' );
        return in;
    }
    std::istream& comment2( std::istream& in ) // überliest Kommentar beginnend mit '/'
    {
        while( in >> std::ws && !in.eof() && char(in.peek()) == '/' )
            in.ignore( 999, '\n' );
        return in;
    }
    
    int ExportFixes()
    {
        using namespace std;
        deque< Entry > fx_Entries;                                      // Container mit Struktur "Entry" erstellen
        {
            std::ifstream fx_fwpNavFIX("navdata/wpNavFIX.txt");         // Input- Datei wpNavFix definieren
            for(Entry e; fx_fwpNavFIX >> comment >> e; )                // Einträge von Entry durchlaufen
            {
                fx_Entries.push_back( e );                              // e in fx_Entries einfügen
            }
            sort( fx_Entries.begin(), fx_Entries.end() );               // fx_Entries sortieren
        }
    
        deque< Compare > fx_Compare;
        {
            std::ifstream fx_fFixes("navigation/Fixes.db");             // Input-Datei Fixes definieren
            for( Compare f; fx_fFixes >> comment2 >> f; )               // Einträge von Entry durchlaufen
            {
                fx_Compare.push_back( f );
            }
    //weg: nix weg, nur marker für neue zeile
            stable_sort( fx_Compare.begin(), fx_Compare.end() );//neu
        }
        ofstream fx_OutFile("navigation_new/Fixes.db");                                // Ausgabedatei definieren
        for( deque< Entry >::iterator e = fx_Entries.begin(); e != fx_Entries.end(); ++e ) //fx_Entries durchlaufen
        {
            // --   alle Einträge aus 'navdata/wpNavFIX.txt' sortiert wegschreiben
            //      hinter jeden Eintrag wird die Zahl geschrieben, die in 'navigation_new/Fixes.db' für diesen Eintrag
            //      gefunden wurde. Falls keiner gefunden wurde, so wird eine '5' angehängt.
            fx_OutFile << *e << ';';
    //weg        deque< Compare >::iterator f = find( fx_Compare.begin(), fx_Compare.end(), Compare( e->m_fix ) );
            deque< Compare >::iterator f = lower_bound( fx_Compare.begin(), fx_Compare.end(), Compare( e->m_fix ) );//neu
    //weg        if( f != fx_Compare.end() )
            if( f != fx_Compare.end() && f->m_fix==e->m_fix)//neu
                fx_OutFile << f->m_Number;      // Nummer aus 'navigation_new/Fixes.db' für diesen Eintrag anhängen
            else
                fx_OutFile << '5';              // default ist 5
    //weg        fx_OutFile << endl;
            fx_OutFile << '\n';//neu, endl macht auch flush, nix gut
        }
        return (true);
    }
    


  • 😮 😮 😮

    Ich hab gerade auf Release umgeschaltet und deinen veränderten code eingefügt.

    Resultat : "Fixes Exported in: 0 Hours, 0 Minutes, 14 Seconds"

    Genial, danke!!!!!!
    Was macht lower_bound jetzt so anders, dass es SO viel schneller geht?



  • campinge schrieb:

    Resultat : "Fixes Exported in: 0 Hours, 0 Minutes, 14 Seconds"

    jup, das trifft meine erwartungen.

    miss doch gerade noch, ob es einen merklichen effekt hat, wenn man beiden strukturen noch eine eigene swap-funktion spendiert. das würde glaub ich so gehen:

    struct Entry    // Struktur für das Eingangsfile 
    { 
        bool operator<( const Entry& b ) const    // legt die Reihenfolge bei 'sort' fest 
        { 
            return m_fix < b.m_fix; 
        } 
        std::string m_fix;            // String für das Fix 
        double m_latitude;            // bool für Latitude 
        double m_longitude;            // bool für longlitude 
        friend template <typename T>
        std::swap(Entry& a,Entry& b)
        {
            std::swap(a.m_fix,b.m_fix);
            std::swap(a.m_latitude,b.m_latitude);
            std::swap(a.m_longitude,b.m_longitude);
        }
    }; 
    
    struct Compare    // Strukur für das Vergleichsfile 
    { 
        explicit Compare( const std::string& fix = std::string() )  // Konstruktor für Vergleiche 
            : m_fix( fix ) 
            , m_latitude(), m_longitude() 
            , m_Number() 
        {} 
        bool operator<( const Compare& b ) const    // legt die Reihenfolge bei 'sort' fest 
        { 
            return m_fix < b.m_fix; 
        } 
        bool operator==( const Compare& b ) const 
        { 
            return m_fix == b.m_fix; 
        } 
        std::string m_fix;            // String für das Fix 
        double m_latitude;            // bool für latitude 
        double m_longitude;            // bool für longlitude 
        int m_Number;                // int für die nummer 
        friend template <typename T>
        std::swap(Compare& a,Compare& b)
        {
            std::swap(a.m_fix,b.m_fix);
            std::swap(a.m_latitude,b.m_latitude);
            std::swap(a.m_longitude,b.m_longitude);
            std::swap(a.m_Number,b.m_Number);
        }
    };
    


  • hm, das bringt mir jetzt eine compiler-Fehlermeldung:

    (10) error C2059: syntax error : 'template<'
    (10) error C2899: typename cannot de used outside a template declaration
    (12) error C2334: unexpected token(s) precending '{'; skipping appearant function body

    und das halt 2 mal...



  • ich habs auch verdreht.

    template <typename T> friend
    

    solls heißen.
    sorry. und ich weiß nicht sicher, obs damit dann geht.



  • oha, das hat's sogar noch schlimmer gemacht:

    nur mal ein kleiner Ausschnitt:
    'std::swap' : not a function
    'std::swap' : dependant name is not a type prefix with 'typename' to indicate a type
    'swap' : cannot be a template definition
    binary '==' 'const Compare' does not define this operator or a conversion to a type acceptable.....

    das geht so dann +100 Zeilen weiter o.O
    (56 errors)



  • #include <algorithm>
    


  • ist ja schon drin
    1. Zeile 😉



  • friend template <typename T> 
        std::swap(Compare& a,Compare& b) 
        { 
            std::swap(a.m_fix,b.m_fix); 
            std::swap(a.m_latitude,b.m_latitude); 
            std::swap(a.m_longitude,b.m_longitude); 
            std::swap(a.m_Number,b.m_Number); 
        }
    

    Eine friend -Definition? Geht das?

    Ansonsten machst du einfach ein eigenes swap() .



  • jetzt hab ich wieder die fehlermeldungen von oben, klappt also auch nicht.
    Was ist denn jetzt eigentlich dieses swap?



  • campinge schrieb:

    jetzt hab ich wieder die fehlermeldungen von oben, klappt also auch nicht.
    Was ist denn jetzt eigentlich dieses swap?

    http://www.cplusplus.com/reference/algorithm/swap.html

    Reduzier deinen Code mal so, dass du den selbern Fehler noch hast und das hier posten kannst.



  • folgendes ist gerade erfolgreich durchgelaufen:

    template <typename T>
        void swap(Entry& a,Entry& b)
        {
            std::swap(a.m_fix,b.m_fix);
            std::swap(a.m_latitude,b.m_latitude);
            std::swap(a.m_longitude,b.m_longitude);
        }
    

    hat 11 sekunden gedauert, also nocht mal 3 sekunden schneller geworden 🙂



  • campinge schrieb:

    Was ist denn jetzt eigentlich dieses swap?

    Das soll zwei Instanzen tauschen.

    Versuchs doch mal mit Spezialisierung von std::swap() (hier bin ich mir nicht ganz sicher, ob das vom Standard erlaubt ist, aber ich meinte, schon)

    template <>
    void std::swap<Compare>(Compare& Right, Compare& Left)
    {
    	std::swap(Left.m_fix, Right.m_fix); 
    	std::swap(Left.m_latitude, Right.m_latitude); 
    	std::swap(Left.m_longitude, Right.m_longitude); 
    	std::swap(Left.m_Number, Right.m_Number); 
    }
    

    Oder mit Überladung (nicht im Namensraum std )

    void swap(Compare& Right, Compare& Left)
    {
    	std::swap(Left.m_fix, Right.m_fix); 
    	std::swap(Left.m_latitude, Right.m_latitude); 
    	std::swap(Left.m_longitude, Right.m_longitude); 
    	std::swap(Left.m_Number, Right.m_Number); 
    }
    

    Und dann entsprechende friend -Deklarationen in der Klasse. Schöner wäre natürlich, eine Memberfunktion swap() anzubieten, dann kann die von der globalen Funktion aufgerufen werden.


Anmelden zum Antworten