2014-03-04 27 views
1

我需要編寫一個小函數,它使得一個新的std :: set從現有的元素中取出最後的n個元素。C++爲所有std :: sets寫一個泛型函數

下面是代碼:

template <typename S, typename T, typename Z> 
std::set<T,S,Z> get_first_subset(std::set<T,S,Z> const& set, size_t size) { 
    if (size == 0) 
     return std::set<T,S,Z>(); 

    typename std::set<T,S,Z>::reverse_iterator j = set.rbegin(); 
    std::advance(j, size - 1); 

    return std::set<T,S,Z> ((++j).base(), set.end()); 
} 

它的工作原理,但因爲我並不需要訪問類型T,S,和ZI想知道如果有一種方法可以簡單地說「任何的std ::設置「沒有三個模板參數。

回答

1

怎麼樣讓它更通用的:

#include <iterator> 
template <typename T> 
T get_first_subset(T const& set, size_t size) { 
    if (size == 0) 
    return T(); 

    typename T::reverse_iterator j = set.rbegin(); 
    std::advance(j, size - 1); 

    return T ((++j).base(), set.end()); 
} 

然後:

int main() { 
    std::set<int> s{10, 2,4,6,7,8,9}, s1; 
    s1 = get_first_subset(s, 4); 
    for (auto i:s1) std::cout << i << " "; 
    std::cout << std::endl; 
} 

輸出:

7 8 9 10 

您還可以使用可變參數模板(C++ 11)大括號初始化和auto關鍵字以避免重複自己:

template <typename ...S> 
std::set<S...> get_first_subset(std::set<S...> const& set, size_t size) { 
    if (size == 0) return {}; 
    auto j = set.rbegin(); 
    std::advance(j, size - 1); 
    return {(++j).base(), set.end()}; 
} 
+0

嗯,是的。我想它是有效的。我仍然很好奇,如果我想要一個特定的標準數據結構,可以避免所有這些模板參數。 –

+0

@ Paolo.Bolzoni - 你關心的是用法或函數定義和簽名?因爲如果它是用法並且你可以使用'C++ 11',你可以使用'auto'並且得到類似(_not_ tested)的東西:'auto subset = get_first_subset(some_set,some_size);'。 –

+0

@ Paolo.Bolzoni您可以在C++ 11中使用可變參數模板來避免指定多個模板參數 – piwi

相關問題