我最近正在研究一個C++庫,在那裏我設計了一個模板類,出於效率和安全的原因,我們需要特別是非多態的。爲了確保以後我沒有忘記這一點,並意外地破壞了一切,我認爲我會成爲一個好公民,併爲此添加靜態斷言。確保模板類不是多態的?
我最初嘗試是這樣的:
template <typename T> class VirtualVerboten {
...
static_assert(!std::is_polymorphic<VirtualVerboten>::value,
"This should not be polymorphic."); // Error!
};
這並不是因爲編譯,在我使用VirtualVerboten
的時間,這是一個不完整的類型。如果這是一個非模板類,我只是把static_assert
類型之後:
class NonTemplateVirtualVerboten {
...
}
static_assert(!std::is_polymorphic<NonTemplateVirtualVerboten>::value,
"This should not be polymorphic.");
但由於這是一個模板類,使得「模板static_assert
」的類似想法是不合法的:
template <typename T> class VirtualVerboten {
...
};
template <typename T>
static_assert(!std::is_polymorphic<VirtualVerboten>::value,
"This should not be polymorphic."); // Error!
我想出瞭解決的辦法是找到VirtualVerboten
內的成員函數,將有可能被用來當模板實例化(具體而言,構造函數),然後把靜態斷言在那裏:
template <typename T> class VirtualVerboten {
VirtualVerboten();
};
template <typename T>
VirtualVerboten<T>::VirtualVerboten() {
static_assert(!std::is_polymorphic<VirtualVerboten>::value,
"This should not be polymorphic."); // Yay!
doSomeActualThingsAtRuntime();
}
這是有效的,只是它依賴於這個特定的構造函數實際上會被調用並因此實例化的事實,如果有多個可以調用的構造函數會失敗。
有沒有一種「萬無一失」的方式來在這裏添加這個靜態斷言?我明白爲什麼原始代碼會產生一個錯誤,爲什麼你不能有模板靜態斷言,所以這更像是「我錯過了另一種這樣做的方式嗎?」而不是「這就是爲什麼你所做的不起作用。」
呃?構造函數?不得不在某個地方建造這個類。在那裏推你的靜態斷言。 –
@SamVarshavchik這就是我最終做的。也許我應該編輯這個問題,使其更清晰。 – templatetypedef
您只需要將某個類型封裝在某個相關的東西中,這樣只會在第二階段中檢查靜態斷言。 –