https://stackoverflow.com/a/332086/462608

la modification d'une valeur précédemment const n'est indéfinie que si la variable d'origine est const

...

si vous l'utilisez pour retirer le const d'une référence à quelque chose qui n'a pas été déclaré avec const, c'est sûr.

...

Cela peut être utile lors de la surcharge de fonctions membres basées sur const, par exemple. Il peut également être utilisé pour ajouter const à un objet, par exemple pour appeler une surcharge de fonction membre.

Je suis incapable de comprendre la signification des citations ci-dessus. Je vous demande de me donner des exemples pour montrer pratiquement ce que signifient ces citations.

0
Aquarius_Girl 28 août 2020 à 11:21

2 réponses

Meilleure réponse

Concernant vos deux premières citations:

void do_not_do_this(const int& cref) {
    const_cast<int&>(cref) = 42;
}

int main() {
    int a = 0;
    // "if you use it to take the const off a reference 
    // to something that wasn't declared with const, it is safe."
    do_not_do_this(a);  // well-defined
        // a is now 42.
    
    // "modifying a formerly const value is only 
    //  undefined if the original variable is const"
    const int b = 0;
    do_not_do_this(a);  // undefined behavoiur
}

Concernant votre devis final:

// "This can be useful when overloading member functions based
//  on const, for instance. It can also be used to add const
//  to an object, such as to call a member function overload."
class A {
    const int& get() const
    {
        // ... some common logic for const and
        // non-const overloads.
        return a_;
    }

    int& get() {
        // Since this get() overload is non-const, the object itself
        // is non-const in this scope. Moreover, the a_ member
        // is non-const, and thus casting away the const of the return
        // from the const get() (after 'this' has been casted to
        // const) is safe.
        A const * const c_this = this;
        return const_cast<int&>(c_this->get());
    }
    
private:
    int a_{0}; 
}
6
G. Sliepen 28 août 2020 à 09:18

Que dis-tu de ça:

#include <iostream>
void foo(const int& ub, const int& ok)
{
    const_cast<int&>(ub) = 0.0; // undefined behaviour - the original object is const
    const_cast<int&>(ok) = 1.0; // this is fine - the original object is not const
}

int main()
{
    const int ub = 1.0;
    int ok = 0.0;
    foo(ub, ok);
    std::cout << ub << " " << ok << std::ends;
}

Notez que la sortie sur les compilateurs courants est 1 1: la raison étant que le compilateur sait que ub ne peut pas changer dans main donc il remplace 1 par ub dans le {{X4} } appel.

Votre troisième paragraphe fait allusion à un corps de fonction d'une fonction non membre - const appelant la version const comme moyen d'éviter la répétition du code.

3
Bathsheba 28 août 2020 à 09:11