I have an abstract class that declares const and non-const member functions. For the sake of discussion let's say it looks like this:
class record_interface
{
public:
virtual ~record_interface() = default;
virtual void set_foo(BoundedFloat) = 0;
virtual BoundedFloat get_foo() const = 0;
};
This is used as a high-level representation of a record that has different representations when saved to disc and transferred via the wire. So most implementations just need to convert their members to the required high-level representation.
As an example of a valid implementation let's define stored_record
. This is used to store the high-level record in a lossy format:
struct stored_record
{
int16_t foo;
};
It makes sense that stored_record
can implement record_interface
but for various reasons it can't (eg. it needs to be trivially_copyable
). We can make a wrapper that implements the interface for it:
class record_wrapper : public record_interface
{
public:
record_wrapper(stored_record & wrapped)
: wrapped_(wrapped) {}
void set_foo(BoundedFloat value) final { wrapped_.foo = convert_to_int16(value); }
BoundedFloat get_foo() const final { return convert_from_int16(wrapped_.foo); }
private:
stored_record & wrapped_;
};
Now the problem is that we can't use the wrapper when given a const stored_record &
since
the wrapper stores a mutable reference. We also can't make it store a non-const reference as it won't be able to implement the non-const setter function.
Now I was wondering if it would be valid to provide a factory function that const_cast
s away
a const stored_record &
's const
but also returns a const wrapper
so that the reference cannot actually be modified:
record_wrapper make_wrapper(stored_record & wrapped) {return {wrapped}; }
record_wrapper const make_wrapper(stored_record const & wrapped) { return {const_cast<stored_record &>(wrapped)}; }
EDIT: returning a const
record_wrapper
will not really restrict the returned value to be const
, a solution can be to return a const_wrapper<record_wrapper>
or something similar.
Is this a valid usage of const_cast
or is it undefined behaviour due to const_cast
ing away the const
-ness of a reference to an actually const object - even though it is never modified through it.