2011-09-19 79 views
1

我想更改const函數參數的成員。想象一下從質感一流這個片段我的工作:有沒有辦法改變一個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,但不會允許我指定的設置參數默認參數,或致電函數與臨時變量。

我想我可以使設置struct的副本loadPixels函數內部,但我想避免這種情況。任何其他想法?

編輯:

好吧,我決定去與可變keyword.-這是爲什麼:我的方案的設置結構基本上只有像素的紋理/加載的施工過程中使用,沒有存儲之後.-因此,mutable不會改變任何關於用戶的常量,因爲它不能被訪問。重載似乎是一種痛苦在我situtation,因爲我實現各種類型(即無符號的字符,短整型,整型......),因此只是超載會增加的源代碼量很多的loadPixels方法。順便說一句。在實際工作中設置得到保存一個PIMPL對象(其loadPixel功能沒有模板,因此不知道類型的任何東西)這就是爲什麼我想直接在常量設置結構的工作中。

+3

你可以聲明'Settings :: pixelDataType'爲'mutable'。 –

+1

對於非可變數據,您應該使用'const',而不是讓您能夠使用臨時對象。不要繞開系統。 –

+0

一個耶可變關鍵字是我在找的,謝謝! @Tomalak,以及我很確定,這是一個例外,它是有道理的! – moka

回答

5

你有兩個選擇:

  1. 做一個const_cast <>()
  2. 標記成員作爲mutable

但是,只要你想更新consty和非consty的事情,我想你想用一個非const版本過載函數:

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

,然後將通用代碼放入另一個函數中。

+2

或許可變應該來第一,因爲它是不那麼邪惡 – tstenner

+3

也許關於超載的建議應該獨自一人,沒有任何罪惡 –

4

目前還不清楚我爲什麼你要修改的設置參數。

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

其他建議似乎不太好。將常量強制轉換爲修改常量對象會導致未定義的行爲。此外,使普通數據成員變爲可變的並不是一個好主意,因爲它會使const關鍵字失去其大部分值。

如果你想避免一個副本,但參考/存儲指向設置,這不是一個好主意,因爲設置對象的生命週期可以很容易地比紋理對象短。製作副本將在這裏提供最健壯的代碼。

作爲一種替代方法,您可以完全刪除PixelDataType::Auto,並且讓Settings將此成員初始化爲Float32本身(例如,默認情況下)。

+1

+1:我喜歡這個答案。 –

相關問題