這是我經常遇到的RAII問題。我想知道是否有人有一個好的解決方案。RAII和推導出的模板參數
開始用你的標準RAII實用類:
class RAIIHelper {
RAIIHelper() {
AcquireAResource();
}
~RAIIHelper() {
ReleaseTheResource();
}
};
現在,由於種種原因,我需要使它成爲一個模板。我們還假設其構造函數模板參數類型的參數:
template <typename T>
class RAIIHelper {
RAIIHelper(T arg) {
AcquireAResource();
}
~RAIIHelper() {
ReleaseTheResource();
}
};
現在考慮使用場所:
void func() {
RAIIHelper<SomeType> helper(someObj);
}
這很煩人有寫出來SomeType
時,它可以從someObj
推斷,所以我寫了一個輔助函數來推斷類型:
template <typename T>
RAIIHelper<T> makeRAIIHelper(T arg) {
return RAIIHelper<T>(arg);
}
現在我可以用它像這樣:
void func() {
auto helper = makeRAIIHelper(someObj);
}
很好,對不對?除了有一個障礙:RAIIHelper
現在需要是可複製或可移動的,而釋放資源的析構函數可能會被調用兩次:一次爲makeRAIIHelper
返回的臨時值,一次爲調用函數中的局部變量。
實際上,我的編譯器執行RVO,析構函數只被調用一次。但是,這不能保證。從這個事實可以看出,如果我試圖給RAIIHelper
一個= delete
'd移動構造函數,代碼不再編譯。
我可以向RAIIHelper添加額外的狀態,以便它知道在移動之後不會調用ReleaseTheResource()
,但這是在添加makeRAIIHelper()
以獲得類型扣除之前不必要的額外工作。
有沒有一種方法可以得到類型扣除,而不必爲RAIIHelper
增加額外的狀態?
在旁邊,看起來你正在重新創造'unique_ptr',你確定絕對沒有天生的'SomeType'類型的哨兵對象嗎? – Deduplicator
你可以使用'unique_ptr'。 –
編寫適當的移動構造函數並禁用複製構造函數。這應該不成問題。 –