tags:

views:

263

answers:

6

Hi,

As a common rule, it is very often considered a bad practice to use const_cast<>() in C++ code as it reveals (most of the time) a flaw in the design.

While I totally agree with this, I however wonder what are the cases were using const_cast<>() is ok and the only solution.

Could you guys please give me some examples you know/you encountered ?

Thank you very much.

+10  A: 

it is pretty much designed to be only used with legacy APIs that are not const correct i.e. with a function you can't change that has non const interface but doesn't actually mutate anything on the interface

jk
A: 

Yes of course, when your calling code that you can't modify and isn't const correct. It should be noted that you should only use it with calls to functions that you know for certain won't modify your data!

Ivan
+6  A: 

I agree with your statement that its normal use is because you need to hide a 'design flaw'.

IME one of the typical usage scenarios is when you try to interface C++ to existing C code. A lot of existing C code takes C strings as char * even when the string is not modified whereas they're usually represented as something that converts to a const char * in C++. That's an impedance mismatch between the two languages that you would normally solve by using a const_cast. Of course you'd better be very sure that the code you're interfacing with doesn't get any cute ideas about modifying the data that's being passed in.

I would say that it's a code smells in newly written code, but for interfacing with older C and C++ code, it's an necessary evil. That said, I would be extremely wary of code that requires const_cast for any non-POD objects as that is normally a problem that should be solved at the design level and not the code level.

Timo Geusch
A: 

One very legitimate use of this is when you have both a const and non const api (for const and non const objects respectively) as in

class Bar {
   const SomeType& foo() const; 
   SomeType& foo();
}

Then since we don't want to duplicate the code in both functions we often use

class Bar {
   SomeType& foo() {
      //Actual implementation 
   }
   const SomeType& foo() const {
        return const_cast<Bar*>(this)->foo();
   }
};

This is of course assuming that foo does not do something that violates the const semantics.

Jasmeet
You have that backwards, and it may lead to undefined behavior.
GMan
care to elaborate ?
Jasmeet
The concern is that the non-const version of `foo` might modify `this`, and so it is "unsafe" to call it on a const object that you've cast to non-const. It's "safe" to call a const member function on a non-const object, so GMan's version is preferable. However, GMan's version also may lead to undefined behaviour when the client modifies the returned value, as I commented on his answer.
Steve Jessop
@Steve Jessop, my last sentence states "This is of course assuming that foo does not do something that violates the const semantics.". That was the assumption. Although I agree you can do it both ways.@Dennis Zickefoose - I originally thought that you were implying that just casting away constness leads to undefined behavior, which is clearly not true. However on reading your comment again, it seems that you are saying the same thing as Steve Jessop, so I guess I have the same answer.
Jasmeet
"That was the assumption". Sure, and GMan (along with Scott Meyers) point out that this is not a wise assumption to make, nor a necessary one.
Steve Jessop
A: 

Like others have said, it's primary purpose to to remove const from objects to pass to non-const correct functions you know won't modify the argument.

There is a trick (by Meyers?) to avoid code duplication, and it goes like this:

struct foo
{
    const return_type& get(void) const
    {
        // fancy pants code that you definitely
        // don't want to repeat

        return theValue; // and got it
    }

    return_type& get(void)
    {
        // well-defined: Add const to *this,
        // call the const version, then
        // const-cast to remove const (because
        // *this is non-const, this is ok)
        return const_cast<return_type&>(static_cast<const foo&>(*this).get());
    }
};
GMan
I think this trick is almost always worse than duplicating the contents of `get() const` in `get()`. In the cases where this is better than copy and paste, a template helper (instantiated once for const and once for non-const) would be even better, since it would allow the compiler to verify that the fancy pants code really does return something modifiable in the case where `this` is modifiable. It might not, it might sometimes return a reference to a `const` global variable, so this trick forces you to manually verify the const-correctness of fancy pants code. Bad.
Steve Jessop
@Steve: I'd rather do this copy paste. In the special case where this trick won't work, don't use it.
GMan
What if the "fancy pants" code is 0 lines, and `get` just returns a data member? Would you avoid copy-paste then? My claim is that there are no good cases for this trick. Either the code is simple enough to copy-paste, or else it is too complex to analyse manually for const-correctness. There's no middle ground which is too much to copy, but little enough that you don't want automated const-correctness. In Meyer's example IIRC the fancy-pants code is a bounds-check: so put the check in a helper function, same way we normally share code ;-)
Steve Jessop
"If it won't work, don't use it" is all very well, but requires manual const-analysis to figure out whether it will work or not. If it's OK to do manual const-analysis, why are we bothering with const and non-const versions of member functions in the first place?
Steve Jessop
+2  A: 

const_cast is also used to remove volatile modifiers, as put into practice in this (controversed) article:

http://www.drdobbs.com/184403766

Alexandre C.
I just learnt something great ! Thank you **very** much !
ereOn