2015-10-07 72 views
4

下面的代碼可以讓我到模板的功能 進行參數是三種不同的指針類型來框對象向量:模板函數來處理階級和階級*

const std::vector<std::shared_ptr<Box>>& 
const std::vector<std::weak_ptr<Box>>& 
const std::vector<Box*>& 

是否有辦法將其擴展爲支持:

const vector<Box>& 
const vector<std::reference_wrapper<Box>> 

也許是在提升?

#include <vector> 
#include <iostream> 

class Box{ 
public: 

    Box (unsigned int id, unsigned int side): id(id), side(side){} 

    int volume(){ 
     return side * side * side; 
    } 
    unsigned int id; 
    unsigned int side; 

}; 

template <typename T> 
struct is_box_containter { 
    enum { value = false }; 
}; 

template <> 
struct is_box_containter <std::vector<std::shared_ptr<Box>>> { 
    enum { value = true }; 
}; 

template <> 
struct is_box_containter <std::vector<std::weak_ptr<Box>>> { 
    enum { value = true }; 
}; 

template <> 
struct is_box_containter <std::vector<Box*>> { 
    enum { value = true }; 
}; 

template <typename T> 
typename std::enable_if<is_box_containter<T>::value>::type 
measure(T const& boxes) 
{ 
    for (auto& box : boxes) { 
     std::cout << box->id << " has volume " << box->volume() << std::endl; 
    } 
} 

int main(){ 

    std::vector<std::shared_ptr<Box>> some_boxes; 
    some_boxes.push_back(std::shared_ptr<Box>(new Box(1,4))); 
    some_boxes.emplace_back(new Box(2, 12)); 
    Box * box_3 = new Box(3, 8); 
    Box * box_4 = new Box(4, 9); 

    std::vector<Box*> more_boxes; 
    more_boxes.emplace_back(box_3); 
    more_boxes.emplace_back(box_4); 

    measure(some_boxes); 
    measure(more_boxes); 

    return 0; 
} 

爲什麼我問這個問題: 我有幾乎相同的邏輯,其實現兩個功能的應用。一個需要一個SomeClass的列表,另一個需要一個指向SomeClass的向量的向量。 我目前正在計劃重構代碼來將SomeClass的列表替換爲SomeClass的共享指針列表。但我這樣做的唯一原因是將邏輯轉移到一個通用實現。如果有一個完全合理的方法來避免它,我不想那樣做。

+0

您基本上想知道vasriable是否來自'vector &'? –

+0

我不認爲這就是我的意思,我想知道是否有一種方法來模板可以處理Class和Class *的函數,來編寫將被解釋爲box-> id或box的代碼。身份證號碼。看起來像其他人可能會遇到的問題,增強庫的編寫類型。其實我不知道這是否只是一個問題,我不知道正確的詞彙表,所以我沒有充分使用Google。 –

+0

你嘗試重疊嗎? –

回答

4

如果我理解正確你的問題,你可以使用非關聯化的機制象下面這樣:

template<typename T> 
T& dereference(T &v) { 
    return v; 
} 

template<typename T> 
const T& dereference(const T& v) { 
    return v; 
} 

template<typename T> 
typename std::enable_if<!std::is_function<T>::value, T&>::type dereference(T* v) { 
    return dereference(*v); 
} 

template<typename T> 
const T& dereference(const std::shared_ptr<T>& v) { 
    return dereference(*v); 
} 

template<typename T> 
const T& dereference(const std::weak_ptr<T>& v) { 
    return dereference(*v); 
} 

template<typename T> 
const T& dereference(const std::reference_wrapper<T>& v) { 
    return v; 
} 

,然後打電話給你的數據,如:

template <typename T> 
typename std::enable_if<is_box_containter<T>::value>::type 
measure(T const& boxes) 
{ 
    for (auto& box : boxes) { 
     std::cout << dereference(box).id 
        << " has volume " << dereference(box).volume() << std::endl; 
    } 
} 

LIVE DEMO

PS你」我們也必須定義:

template <> 
struct is_box_containter <std::vector<Box>> { 
    enum { value = true }; 
}; 

template <> 
struct is_box_containter <std::vector<std::reference_wrapper<Box>>> { 
    enum { value = true }; 
}; 
+0

ha!當然 - 那很漂亮 –