2016-07-27 34 views
0

之前可能已經提出並回答了這個問題,但我一直無法找出搜索條件來找到它。這裏是一些代碼來顯示我的問題(打算作爲僞代碼...如果需要澄清)。如何確定從類模板繼承的模板參數的底層模板類型?

image.h的:

template <class T> 
class Image 
{ 
    public: 
     // Return pointer to data. 
     T* GetValues(); 

     std::vector<T> data_; 

}; 

template <class T> 
T* Image<T>::GetValues() 
{ 
    return &data_[0]; 
} 

SpecialImage.h

class SpecialImage : public Image<float> 
{ 

} 

Stack.h

template<class T> 
class Stack 
{ 
    public: 

     void NegateAllImageValues(); 

     std::vector<T> stackOfImages_; 
}; 

template <class T> 
void Stack::NegateAllImageValues() 
{ 
    for(int i = 0; i < stackOfImages_.size(); ++i) 
    { 
     // Type L should be float if T=SpecialImage, but how to get? 
     L* imageValues = stackOfImages_.at(i).GetValues(); 

     // Loop over values and multiply by -1.0. 
    } 
} 

的main.cpp

{ 
    // Create stack of SpecialImages. 
    Stack<SpecialImage> myStack; 

    // Create special image and add some data. 
    SpecialImage mySpecialImage; 
    mySpecialImage.data_.push_back(1.0f); 
    mySpecialImage.data_.push_back(2.0f); 
    mySpecialImage.data_.push_back(3.0f); 

    // Add special image to stack. 
    myStack.stackOfImages_.push_back(mySpecialImage); 

    // Negate all values in all SpecialImages in the stack. 
    myStack.NegateAllImageValues(); 

} 

我的問題是如何知道Stack :: NegateAllImageValues中的類型L?我意識到我可以編寫一個方法Image :: NegateAllValues並從Stack :: NegateAllImageValues中調用它,但我想知道是否有方法在堆棧級別獲取類型L.我想我可以額外的模板參數添加到函數棧:: NegateAllImageValues像

template <class T, class L> 
void Stack::NegateAllImageValues() 
{ 
    for(int i = 0; i < stackOfImages_.size(); ++i) 
    { 
     // Type L should be float if T=SpecialImage, but how to get? 
     L* imageValues = stackOfImages_.at(i).GetValues(); 

     // Loop over values and multiply by -1.0. 
    } 
} 

但隨後的L型不強制匹配圖像的基本模板類型。

這裏有一個固有的設計缺陷嗎?有沒有辦法在堆棧級別獲得L型?

+1

通過添加以下內容來捕獲該類型:'using valueType = T;'到'Image' –

+0

還有'auto',但是,'Image'應該具有該類型的別名。 – LogicStuff

回答

3

經典的方式做,這是把一個typedef /別名在Image類,像

template <typename T> 
class Image { 
public: 
    typedef T value_type; 

    // Other stuff 
}; 

然後在你隨後的Stack::NegateAllImageValues()方法,你可以說

template <class T> 
void Stack::NegateAllImageValues() 
{ 
    for(int i = 0; i < stackOfImages_.size(); ++i) 
    { 
     typename T::value_type* imageValues = stackOfImages_.at(i).GetValues(); 

     // Loop over values and multiply by -1.0. 
    } 
} 

這些種基本上每個標準庫中的模板類都使用typedefs:例如,std::vector<T>包含(除其他之外)成員類型定義value_type,它是T的別名。

在C++ 11和較新的一個替代方案是使用auto代替,例如:

template <class T> 
void Stack::NegateAllImageValues() 
{ 
    for(int i = 0; i < stackOfImages_.size(); ++i) 
    { 
     auto* imageValues = stackOfImages_.at(i).GetValues(); 

     // Loop over values and multiply by -1.0. 
    } 
} 

[普通auto將工作一樣好auto*,但我更喜歡後者,因爲它清楚地表明。你期待一個指針類型]

最後,在C++ 11可以使用decltype獲得的GetValues()返回類型:

template <class T> 
void Stack::NegateAllImageValues() 
{ 
    for(int i = 0; i < stackOfImages_.size(); ++i) 
    { 
     using value_type = decltype(stackOfImages_.at(i).GetValues()); 
     value_type imageValues = stackOfImages_.at(i).GetValues(); 

     // Loop over values and multiply by -1.0. 
    } 
} 

雖然這並不能真正爲你帶來任何益處auto

+0

完美,謝謝! – user1777820