Есть ли способ изменить член const структуры? - PullRequest
1 голос
/ 19 сентября 2011

Я хочу изменить член аргумента функции const.представьте себе этот фрагмент из класса текстур, над которым я работаю:

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

Я знаю, что мог бы сделать аргумент не-const, но это не позволило бы мне указать аргумент по умолчанию для аргумента настроекили вызовите функцию с переменной temp.

Я думаю, я мог бы сделать копию настроек struct внутри функции loadPixels, но я бы хотел этого избежать.Любые другие идеи?

РЕДАКТИРОВАТЬ:

Хорошо, я решил пойти с изменяемым ключевым словом. Вот почему: в моем сценарии структура Настройки в основном используется тольково время построения текстуры / загрузки пикселей и не сохраняется впоследствии. - Таким образом, mutable не меняет ничего о константности для пользователя, так как он просто недоступен.Кажется, перегрузка в моей ситуации более болезненна, поскольку я реализую метод loadPixels для различных типов (например, unsigned char, short, int ...), поэтому просто перегрузка увеличит объем исходного кода alot .Btw.настройки actall сохраняются внутри объекта pimpl (функция loadPixel которого не шаблонизирована и, следовательно, ничего не знает о типе), поэтому я хочу работать непосредственно над структурой const Settings.

Ответы [ 3 ]

5 голосов
/ 19 сентября 2011

У вас есть два варианта:

  1. Сделать const_cast <> ()
  2. Отметить участника как mutable

Но, как вы хотитеобновить const-y и неконстантные вещи, я думаю, вы хотите перегрузить функцию неконстантной версией:

template<>
void mySuperTexture::loadPixels<float>(uint32 _width, uint32 _height, float * _pixels, Settings & _settings)

, а затем поместить общий код в другую функцию.

4 голосов
/ 19 сентября 2011

Мне непонятно, почему вы должны изменять параметр настроек.

int pixelDataType = _settings.pixelDataType;
if (pixelDataType == PixelDataType::Auto) {
   pixelDataType = PixelDataType::Float32;
}

Другие предложения не кажутся обоснованными. Отбрасывание constness для изменения объекта const приводит к неопределенному поведению. Также не стоит делать изменяемыми совершенно обычные элементы данных, так как это приведет к тому, что ключевое слово const потеряет большую часть своего значения.

Если вы хотите избежать копирования, но сохранить ссылку / указатель на настройки, это не очень хорошая идея, поскольку время жизни объекта настроек может быть короче, чем у объекта текстуры. Создание копии даст наиболее надежный код здесь.

В качестве альтернативы вы можете полностью избавиться от PixelDataType::Auto, и Settings инициализирует этот элемент как Float32 (например, по умолчанию).

0 голосов
/ 19 сентября 2011

Если вы действительно знаете, что делаете, вы можете отбросить константность (см. http://www.cplusplus.com/doc/tutorial/typecasting/), но использование константного приведения почти всегда является признаком плохого дизайна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...