我最近遇到了一個問題,我可以看到避免它的唯一方法是使用const_cast - 但我猜想有一種方法,我沒有想到避免這種情況改變代碼的功能。下面的代碼片段將我的問題提煉成一個非常簡單的例子。const_cast問題與std :: map
struct Nu
{
Nu() {v = rand();}
int v;
};
struct G
{
~G()
{
for(auto it = _m.begin(); it != _m.end(); it++) delete it->first;
}
void AddNewNu()
{
_m[new Nu] = 0.5f;
}
void ModifyAllNu()
{
for(auto it = _m.begin(); it != _m.end(); it++) it->first->v++;
}
float F(const Nu *n) const
{
auto it = _m.find(n);
// maybe do other stuff with it
return it->second;
}
map<Nu*, float> _m;
};
這裏,假設努實際上是一個非常大的結構體,其佈局已經被需要匹配外部庫(以及因此的「浮動」固定不能簡單地被摺疊成努,以及用於各種其它原因不能是map<Nu, float>
)。 G結構有一張地圖,它用來保存它創建的所有Nu(最終在銷燬時全部刪除它們)。正如所寫的,函數F不會編譯 - 它不能像std :: map所期望的那樣強制轉換(Nu Nu * n)到(Nu n)。但是,映射無法切換到map<const Nu*, float>
,因爲一些非const函數仍然需要修改Nu的內部_m。當然,我可以將所有這些Nu都存儲在一個額外的std :: vector中,然後將地圖類型切換爲const - 但這會引入一個完全不必要的向量。所以我現在想到的唯一選擇是在F函數中使用const_cast(它應該是一個安全的const_cast),我想知道這是否可以避免。
更多的狩獵後此相同的問題已經在此解決:Calling map::find with a const argument
我的C++知識不好,或者你的變量聲明對我沒有意義。在那裏做關鍵字「auto」是什麼? – 2011-04-19 22:09:41
如果「一些非const函數仍然需要修改Nu的內部_m」,那麼Nu不能用作映射關鍵字。一旦它被修改,地圖不再被排序。 – Cubbi 2011-04-19 22:10:27
@Joris,'auto'是C++ 0x的新特性 - 也許有些編譯器已經支持它了? – 2011-04-19 22:14:39