考慮以下類結構:
template <typename TType>
struct Base {public: virtual ~Base() {} };
template <typename TType>
struct Child : Base<TType> {};
template <template<typename> class Node, typename TType>
bool type(Node <TType>* node){
return dynamic_cast<Base<TType>*>(node) == nullptr;
}
int main(){
Child<int> child;
type(&child);
}
這段代碼作業正常,只要孩子在轉換之前和之后具有相同的模板型別。如果不是這種情況,它當然會失敗。如果它們有不同的型別并且我提供了繼承模板的特定型別,它會起作用,但是我有大量可能的模板。我的第一反應是添加另一個模板:
template <template<typename TType> class Node, typename TType, typename TType2>
bool type(Node <TType>* node){
return dynamic_cast<Base<TType2>*>(node) == nullptr;
}
這將給出錯誤“無法推斷模板引數”,因為編譯器不知道它是哪種型別,因為沒有傳遞相應的引數(但我無法事先提供)。
有什么解決辦法嗎?我也對除了 dynamic_cast 之外的其他可能性持開放態度,因為我的實際目標是,如果模板化節點是也是模板化基類的子類。
我試過例如 is_base_of 沒有成功。is_base_of<Base, typeid(child)>::value由于引數中的型別不匹配,圍繞 of 行的某些內容不起作用。
uj5u.com熱心網友回復:
您可能會使用多載:
template <typename T>
constexpr std::true_type IsBaseT(const Base<T>*) { return {}; }
constexpr std::false_type IsBaseT(const void*) { return {}; }
演示
這假設了可訪問的、非歧義的基礎。結果基于靜態型別。
所以你可以把它變成一個特征:
template <typename T>
std::true_type IsBaseTImpl(const Base<T>*); // No impl
std::false_type IsBaseTImpl(const void*); // No impl
template <typename T>
using IsBaseT = decltype(IsBaseTImpl(std::declval<T*>()));
還有一個更通用的形式:
template <template <typname> C, typename T>
std::true_type IsCTImpl(const C<T>*); // No impl
template <template <typname> C>
std::false_type IsCTImpl(const void*); // No impl
template <template <typname> C, typename T>
using IsCT = decltype(IsCTImpl<C>(std::declval<T*>()));
template <typename T>
using IsBaseT = IsCT<Base, T>;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/342885.html
