2015-05-29 83 views
0

我想了解類型特徵的概念。從基類使用類型特徵

說,我有一些模板化的類層次像這樣和客戶端功能:

template<typename T> 
class Base 
{ 
public: 
//... 
    virtual bool inline isSymmetric() const = 0; 
};  

template<typename T> 
class ChildrenOperation : public Base<T> 
{ 
public: 
//... 
    virtual bool inline isSymmetric() const override 
    { 
     return true; 
    } 
}; 

template<typename T> 
void clientFunction(const Base<T>& operation) 
{ 
    //... 
    if(operation.isSymmetric()) 
    { 
     // use operation in one way 
    } else { 
     // use operation in another way 
    } 
} 

顯然,clientFunction是多態和不同的孩子能有isSymmetric的不同實現。 但是,由於isSymmetric似乎是不變的,實際上更多的是類型信息,我已經讀過關於類型特徵,我想知道是否有可能重寫客戶端函數而不依賴於運行時的isSymmetric,而是編譯時間。

我試過添加這樣的特質。但我不確定如何專門化它,並在多態環境中使用它。

template <typename T> 
struct is_symmetric { 
    static const bool value = false; 
}; 
+0

爲什麼不重載clientFunction? – Axalo

+5

你不能真正在多態上下文中使用類型特徵,因爲它們對* static *類型的東西進行操作,而虛擬函數對* dynamic *類型進行操作。 – TartanLlama

+0

這段代碼不會像這裏寫的那樣工作。 'Base'是一個模板,但當您將其作爲'clientFunction'中的參數提供時,您不提供模板參數。我想你並不是真的希望'Base'成爲一個模板,只有孩子,但我不確定你打算如何處理這段代碼。 – petersohn

回答

1

如果是對稱的依賴於從Base得出的具體類型,那麼你就不能使用類型性狀這種情況。類型特徵是在編譯時評估的,所以如果你有一個多態類型的特性在編譯時是未知的,那麼你不能使用類型特徵。

一個可能的解決方案,如果對稱性真的是恆定的,是這樣的:

class Base { 
public: 
    Base(bool symmetric) : symmetric(symmetric) {} 

    bool isSymmetric() { 
     return symmetric; 
    } 

    // ... 

private: 
    bool symmetric; 
}; 

class ChildrenOperation : public Base { 
public: 
    ChildrenOperation() : Base(true) {} 

    // ... 
}; 

我這裏沒有,因爲他們是在這種情況下不相關的使用模板。當然,如果對稱性依賴於T,那麼你可以使用類型的特徵,比如:

template <typename T> 
struct is_symmetric : public std::false_type {}; 

template <> 
struct is_symmetric<SymmetricT> : public std::true_type {}; 

因此,解決方案取決於性狀是否只依賴於動態類型的對象,在這種情況下,你應該使用拳頭代碼,模板參數,在這種情況下,您應該使用第二個代碼,或兩者兼而有之。從你的例子來看,你的情況並不完全清楚。