Reputation: 1863
I am dealing with a third party library where I would like to modify a structure for the sake of simplicity in my code.
There is a third party struct
struct structure {
const char *c;
// ...
};
I have a function
void prep(const structure *s) {
std::string str("hello");
const char *t_c = s->c;
s->c = str.c_str(); // structure::c is a const char *
handle(s); // makes use of overriden c
s->c = t_c; // Set back in case library tries to free/use memory later
}
How do I do the appropriate const casting here?
Upvotes: 0
Views: 299
Reputation: 29022
I'm assuming handle
is declared as void handle(const structure*);
.
The easiest solution is to copy s
, modify the copy and then pass it to handle
. Since s
is const
you know that there are no changes that could be made to the copy that would need to be propagated to the original s
. You also eliminate the need to reset s->c
to it's original value.
void prep(const structure *s)
{
structure mycopy(*s); // Make a copy of s
std::string str("hello");
mycopy.c = str.c_str(); // structure::c is a const char *
handle(&mycopy); // makes use of overriden c
}
If you can't copy structure
, consider modifying your function declaration by removing the const
specifier for s
. If you simply remove const
you get the following function which compiles fine. Note that the resulting function is not exception safe. If handle
throws an exception, you will fail to reset the s->c
member to it's original value.
void prep(structure *s)
{
std::string str("hello");
const char *t_c = s->c;
s->c = str.c_str(); // structure::c is a const char *
handle(s); // makes use of overriden c
s->c = t_c; // Set back in case library tries to free/use memory later
}
If all else fails you might be able to use const_cast
as a last resort. Be sure that s
doesn't point to an instance that is actually const
and be sure that no exception is thrown while s
is not in it's original state. Being forced to use of const_cast
may be an indicator of bad design decisions.
void prep(const structure *s)
{
std::string str("hello");
const char *t_c = s->c;
const_cast<structure*>(s)->c = str.c_str(); // structure::c is a const char *
handle(s); // makes use of overriden c
const_cast<structure*>(s)->c = t_c; // Set back in case library tries to free/use memory later
}
Upvotes: 2