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);
}