2012-07-13 85 views
1

在我的工作中,我們做了大量的結對編程,並且我編寫了一個函數,它只接受一個SINGLE類型的容器或其派生類,但是我的co-工人害怕,因爲它看起來那麼該死的醜陋,並說有一定有一個更好的方式,將失敗的代碼審查:模板type_trait函數,接受給定類型和/或派生類型的容器

這裏是簽名,水果類是我改名水果只爲這個線程基類:

template <class Container> 
typename enable_if<is_base_of<Fruit, typename remove_pointer<typename Container::value_type>::type>::value, void>::type 
processFruits(container& fruits) 
{ 
    //process the elements and change them if needed. thats why no const 
} 

它做的是:返回void並啓用該函數如果它是一個容器,並且容器內的類型是一個Fruit和/或deriv被認爲是水果。我也使用std :: remove_pointer因爲我需要知道指針的「類型」(容器最有可能有指針)。

這個編譯和按預期工作,但正如我所說我不知道​​它是它的最佳方式,它似乎太冗長,可能會削減代碼審查。

編輯:這也接受模板類,不一定是容器。有沒有辦法限制它只接受STL容器?

任何替代想法或它是好的嗎? 在此先感謝。

回答

1

閱讀有點恐怖。

對於初學者來說,你不需要說enable_if<B, void>你可以說enable_if<B>並使用默認的模板參數。

您可以輕鬆將其分割成獨立的部分:

template <class T> 
    struct is_fruity 
    : is_base_of<Fruit, T> 
    { }; 

template <class Container, typename Value = typename Container::value_type> 
    struct is_fruit_container 
    : is_fruity<typename remove_pointer<Value>::type>> 
    { }; 

template<class Container> 
    typename enable_if<is_fruit_container<Container>::value>::type 
    processFruits(Container& fruits) 
    { 
    //process the elements and change them if needed. thats why no const 
    } 

如果你有一個編譯器支持別名模板,您可以使其更容易閱讀:

template<typename Cond> 
    using Require = typename enable_if<Cond::value>::type; 

template<class Container> 
    Require<is_fruit_container<Container>> 
    processFruits(Container& fruits) 
    { 
    //process the elements and change them if needed. thats why no const 
    } 

這也接受模板類,不一定是容器。有沒有辦法限制它只接受STL容器?

我不知道你所說的「模板類」的意思,它只接受類型的嵌套value_type類型,是從Fruit或指向這種類型的派生的類型,它沒有被一個模板。要將其限制爲「STL容器」,您需要編寫一個特徵來標識「STL容器」,但是您想要定義它。要做到這一點正確你需要一個特徵,它可測試begin()end()size()成員,以及所有通過容器的需求,指定的嵌套類型,iteratorvalue_type

template<typename C, typename Chead, typename... Ctail> 
struct static_and 
{ 
    static const bool value = C::value && static_and<Chead, Ctail...>::value; 
}; 

template<typename C> 
struct static_and<C> 
{ 
    static const bool value = C::value; 
}; 

template<typename C> 
struct is_container 
: static_and<has_begin<C>, has_end<C>, has_iterator<C>, has_value_type<C> /* etc */> 
{ }; 
+0

感謝了很多的答案,這看起來更容易閱讀,實際上我只是改變了代碼並編譯它,一切正常。模板是如此令人上癮,就像我在大學再次使用prolog一樣。不幸的是沒有別名模板,因爲我們正在使用VS 2010,我不認爲它支持他們..無論如何再次感謝您的幫助:) – sap 2012-07-13 19:39:17

相關問題