When should one use const_cast<>, anyway?
I saw a question on StackOverflow asking about why one would use const_cast. Because I’ve thought about that question lately I glossed over that they were asking specifically about applications of casting away volatile…which I didn’t even know you could use const_cast to do!
So I learned something. But I thought the answer I wrote to why you would use const_cast at all was pretty decent, so I was going to leave it there. But then I decided it was too off topic so I’d move it here.
The most common use of const_cast I’ve seen (with const) is this scenario:
- You’re calling a library that has something like a
printFoo(Foo* fooPointer)function, which clearly requires a non-const Foo. - There’s good reason to be “sure” this function doesn’t modify the Foo, but you’re unable to change the prototype or the source to express that knowledge for some reason.
- Your code has made an effort to only use
Foo*in contexts where writability is needed andconst Foo*in all other contexts.
…that means that as a stopgap measure, you’ll have to const_cast in order to cross this divide and call the routine.
OTOH, the most legitimate use I know of is in subsystems that own objects in a non-const sense, yet have cases where they hand back const pointers to callers. The subsystem natively has more privileges on those objects, so if a caller passes one of those const pointers back it can “upgrade” the privileges.
Sure, the subsystem could store a useless map from non-const pointers to const ones…but const_cast is more time and space efficient:
const SubsystemObject* Subsystem::getReadOnlyObjectById(int id) { SubsystemObject* subsystemObject = getObjectCore(id); #ifdef WORLD_WITHOUT_CONST_CAST constMap[subsystemObject] = subsystemObject; #endif return subsystemObject; } void Subsystem::someMethod(const SubsystemObject* constSubsystemObject) { SubsystemObject* subsystemObject; #ifdef WORLD_WITHOUT_CONST_CAST subsystemObject = constMap[constSubsystemObject]; #else subsystemObject = const_cast<SubsystemObject*>(constSubsystemObject); #endif doSomethingNeedingNonConstAccess(subsystemObject); }
