I want to change a member of a const
function argument. imagine this snippet from a texture class I am working on:
template<>
void mySuperTexture::loadPixels<float>(uint32 _width, uint32 _height, float * _pixels, const Settings & _settings)
{
if (_settings.pixelDataType == PixelDataType::Auto) {
_settings.pixelDataType = PixelDataType::Float32;
// ^ obviously this does not work on the const variable
}
// ...
m_pimpl->loadPixels(_width, _height, _pixels, _settings);
}
I know that I could make the argument non-const
, but that would not all开发者_如何转开发ow me to specify a default argument for the settings argument, or call the function with a temp variable.
I guess I could make a copy of the Settings struct
inside the loadPixels function but I'd like to avoid that. Any other ideas?
EDIT:
Okay, I decided to go with the mutable keyword.- Here is why: In my scenario the Settings struct is basically only used during the construction of the texture/loading of the pixels and not stored afterwards.- Thus the mutable
does not change anything about the constness for the user since its simply not accessible. Overloading does seem to be more of a pain in my situtation since I am implementing the loadPixels method for various types( i.e. unsigned char, short, int ...) thus just overloading would increase the amount of source code alot. Btw. the actuall settings get saved inside a pimpl object (whose loadPixel function is not templated and thus does not know anything about the type) thats why I want to work directly on the const Settings struct.
You have two options:
- Do a
const_cast <> ()
- Mark the member as
mutable
But, as you want to update const-y and non-consty things, I guess you want to overload the function with a non-const version:
template<>
void mySuperTexture::loadPixels<float>(uint32 _width, uint32 _height, float * _pixels, Settings & _settings)
and then put common code into another function.
It is unclear to me why you should be modifying the settings parameter.
int pixelDataType = _settings.pixelDataType;
if (pixelDataType == PixelDataType::Auto) {
pixelDataType = PixelDataType::Float32;
}
Other suggestions don't seem sound. Casting constness away in order to modify a const object leads to undefined behavior. Also it is not a good idea to make perfectly ordinary data members mutable, as it would make the const keyword lose much of its value.
If you want to avoid a copy but store a reference/pointer to the Settings, this is not a good idea, because the lifetime of the Settings object can easily be shorter than the texture object. Making a copy would give most robust code here.
As an alternative you could get rid of PixelDataType::Auto
altogether, and have Settings
initialize this member to Float32
itself (e.g. by default).
If you really know what sou're doing, you could cast the constness away (see http://www.cplusplus.com/doc/tutorial/typecasting/ ), but using const cast is almost always a sign of a bad design.
精彩评论