remove_if



  • Hab eine class parser und darin ein member

    std::string infile_string;
    

    Ich will jetzt alle Ascii-zeichen kleiner 0x20 außer 0x01 entfernen.

    Freie Funktion ist:

    bool IsInvalidChar(const char c) { return ( c < 0x20 && c != 0x01 ); }
    

    aber

    infile_string.resize( std::remove_if(infile_string.begin(), infile_string.end(), IsInvalidChar) - infile_string.begin() );
    

    sagt mir immer nur

    one or more multiply defined symbols found

    Es gibt aber nur diese beiden Zeilen was IsInvalidChar angeht.
    (VC 2005 - also bitte keine lambdas und sowas)

    Für etwas Hilfe wäre ich sehr dankbar. Danke im voraus.


  • Mod

    Versuch mal

    infile_string.erase( std::remove_if(infile_string.begin(), infile_string.end(), IsInvalidChar), infile_string.end() );
    

    Das ist lediglich ein Bug, denn der Code ist völlig korrekt (soweit ich sehen kann und du den echten Code gepostet hast). Hast du aus Versehen infile_string in einem Header ohne inline definiert?

    Wo tritt der Fehler eigentlich auf? In der gezeigten Zeile?



  • ...



  • Arcoth schrieb:

    Versuch mal

    infile_string.erase( std::remove_if(infile_string.begin(), infile_string.end(), IsInvalidChar), infile_string.end() );
    

    Das ist lediglich ein Bug, denn der Code ist völlig korrekt (soweit ich sehen kann und du den echten Code gepostet hast).

    Ich bin recht faul, daher ist alles copy + paste = original code. erase gibt den selben error, trotz dem zig-ten rebuild.

    Arcoth schrieb:

    Hast du aus Versehen infile_string in einem Header ohne inline definiert?

    Kein inline, nirgends. Wieso auch?

    Arcoth schrieb:

    Wo tritt der Fehler eigentlich auf? In der gezeigten Zeile?

    Beim linkem:

    1>ParserDlg.obj : error LNK2005: "bool __cdecl IsInvalidChar(char)" (?IsInvalidChar@@YA_ND@Z) already defined in Parser.obj
    1>M:\Visual Studio 2005\Projects\...\Parser.exe : fatal error LNK1169: one or more multiply defined symbols found



  • EOP schrieb:

    Kein inline, nirgends. Wieso auch?

    Weil es zu Linkerfehlern kommt, wenn die Funktion dann in mehr als einer Übersetzungseinheit landet.



  • Vielen Dank, mit inline funktioniert es problemlos.
    Allerdings verstehe ich nicht wieso es notwendig ist.



  • EOP schrieb:

    Allerdings verstehe ich nicht wieso es notwendig ist.

    Dann informier dich mal über die One Definition Rule.

    Dadurch, dass du den Header mit der Funktionsdefinition sowohl in Parser.cpp als auch in ParserDlg.cpp einbindest, landet die Funktion in zwei Übersetzungseinheiten. Wenn der Linker das dann zusammensetzen soll, kann er nicht entscheiden, welche der zwei Definitionen er benutzen soll.

    Mit inline erlaubst du solche Mehrfachdefinitionen, musst aber dann selbst dafür sorgen, dass alle gleich sind.



  • Wieso kompilieren und funktionieren dann andere klassenlose Funktionen die ich verwende problemlos?
    Alle sind (mit header guard) in einer .h Datei definiert.
    Aber wenn ich diese Funktion auch mit reinstecke gibt's wieder denselben Linkerfehler. Verwirrt mich etwas.



  • Sind diese anderen Funktionen vielleicht static deklariert?

    Zeig doch mal ein Minimalbeispiel, das das Problem reproduziert.



  • Vielleicht werden die anderen zufällig nur in einer Übersetzungseimheit eingebunden?



  • ClassLessFunctions.h

    #ifndef CLASSLESSFUNCTIONS_H
    #define CLASSLESSFUNCTIONS_H
    
    #include <vector>
    
    void unique_vector( std::vector<CString>& vec );
    bool IsInvalidChar(const char c);
    
    #endif
    

    ClassLessFunctions.cpp

    #include "stdafx.h"
    #include "ClassLessFunctions.h"
    #include <algorithm>
    
    void unique_vector( std::vector<CString>& vec )
    {
    	std::sort( vec.begin(), vec.end() );
    	vec.resize( std::unique( vec.begin(), vec.end() ) - vec.begin() );
    } // void unique_vector( std::vector<CString>& vec )
    
    bool IsInvalidChar(const char c)
    {
    	return ( c < 0x20 && c != 0x01 );
    }
    

    Funktioniert problemlos auch z.B. mit MFC-Funktionen.

    EDIT:
    Ist auch in mehreren .cpp-Dateien inkludiert und kompiliert und funktioniert.

    EDIT #2:
    Wenn ich die Funktion nicht gleich im header definiere funktionierts (siehe code).



  • Das ist auch nur eine Deklaration der Funkion im Header, keine Definition.



  • Danke, wieder was gelernt. 🙂


Anmelden zum Antworten