const Referenz schlägt fehl



  • Ich hoffe einfach mal, das dies ein typischer Fehler ist, den man auch ohne Code zu zeigen aufklären kann.

    Ich habe hier zum ersten Mal einen einzigen Fall, bei dem die Übergabe eines komplexen Datentyp per const Referenz nicht funktioniert.
    |error: passing 'const ...' as 'this' argument discards qualifiers [-fpermissive]|

    Ich hatte das immer so verstanden, das diese Art von Übergabe eine Kopie verhindert, allerdings kann ich den Datentyp ganz regulär als call by value übergeben, wo er dann auch nicht verändert werden kann.
    Was kann es denn für Fälle geben, wo die const Referenz fehlschlägt, call by value aber funktioniert?


  • Mod

    Du machst irgendetwas mit dem Objekt, was dieses verändert. Vielleicht unabsichtlich. Jedenfalls machst du irgendetwas, dass für den Compiler so aussieht, als könne es eventuell das Objekt verändern. Höchstwahrscheinlich rufst du eine Methode auf, die nicht als const markiert ist. Mit einer Kopie funktioniert das natürlich, denn das Kopieren wird das konstante Original nicht verändern und mit der Kopie kannst du machen, was du willst.



  • Aber müsste dann call by value nicht auch fehlschlagen?



  • Wenn die Kopie nicht const ist nicht.



  • Danke, dann schaue ich nochmal genauer. Ansonsten muss ich vielleicht doch was zeigen.


  • Mod

    @lemon03 sagte in const Referenz schlägt fehl:

    Danke, dann schaue ich nochmal genauer. Ansonsten muss ich vielleicht doch was zeigen.

    Ich verspreche dir, wir brauchen ungefähr eine Zehntel Sekunde, um den Fehler zu finden, wenn du uns die Fehlermeldung und die zugehörige Codestelle zeigst.



  • Ok, das ist ein Argument 😉 Ich komme auch einfach nicht dahinter.

    if ( !text.empty() )
    {
         //hier erfolgt die Fehlermeldung
         font.print( tx, ty, text, GREY );
    }
    

    mit Hinweis auf
    |note: in call to 'void FIGletFont::print(int, int, const string&, WORD, WORD, bool)'|

    void FIGletFont::printChar( int x, int y, char ch,
                                WORD fg_col, WORD bg_col,
                                bool is_BACKGROUND )
    {
        FIGletChar fchr = getChar( ch );
        std::size_t n = 0;
        for ( int j = 0; j < fchr.height; ++j )
        {
            for ( int i = 0; i < fchr.width; ++i )
            {
                char c = fchr.data[ n++ ];
                if ( c != ' ' )
                {
                    console.printChar( x +i, y +j, c, fg_col, bg_col, is_BACKGROUND );
                }
            }
        }
    }
    
    void FIGletFont::print( int x, int y,
                            const std::string& fulltext,
                            WORD fg_col, WORD bg_col,
                            bool is_BACKGROUND )
    {
        if ( fulltext.back() != ';' )
        {
            std::cerr << "FIGletFont::print(): format warning\n";
            std::cerr << "no separator used\n";
            std::cerr << "text: " << fulltext;
            pressKey();
            return;
        }
    
        std::string text;
        std::vector<std::string> text_vec;
        for ( auto& ch : fulltext )
        {
            if ( ch != ';' )
            {
                text.push_back( ch );
            }
            else
            {
                text_vec.push_back( text );
                text.clear();
            }
        }
        for ( const auto& text : text_vec )
        {
            if ( is_center )
            {
                int text_length = 0;
                for ( auto& ch : text )
                {
                    text_length += getCharWidth( ch );
                }
                x = console.getCenterX() - text_length / 2;
            }
            for ( auto& ch : text )
            {
                printChar( x, y, ch, fg_col, bg_col, is_BACKGROUND );
                x += getCharWidth( ch );
            }
            y += getCharHeight();
        }
    }
    

    Ich hoffe, das reicht?



  • @lemon03 sagte in const Referenz schlägt fehl:

    FIGletFont

    Sieht so aus, als sei font vom Typ const FIGletFont& - dann geht der Aufruf FIGletFont::print nicht, weil dieser nicht const ist.

    Edit:

    Ich hoffe, das reicht?

    Nein, eigentlich nicht. Wichtig ist, von welchem Typ font ist. Meine Vermutung habe ich oben schon geschrieben.


  • Mod

    Ergänzung dazu: Die Funktionen habe ich mir nun nicht im Ganzen durchgelesen, aber vom Namen her sollte man annehmen, dass print und printChar wohl kaum den Objektzustand verändern sollten. Das heißt, es wäre problemlos möglich, diese als const zu kennzeichnen

    void FIGletFont::print( int x, int y,
                            const std::string& fulltext,
                            WORD fg_col, WORD bg_col,
                            bool is_BACKGROUND ) const
    

    Falls das geht, wird es dein Problem lösen. Falls nicht, wird dich dein Compiler an die Stelle in print verweisen, an der das Objekt verändert wird.



  • Juhuu 😃

    Vielen Dank und erst recht an SeppJ. Vielleicht war dies von allen Antwortgebern so gemeint, aber erst jetzt habe ich es verstanden.

    Was bin ich froh, das es nur sone kleine Sache war. Aber wieder was gelernt 🙂


Log in to reply