2017-01-12 53 views
2

我想創建不同類型的容器,並且要使用我的SortedContainer類進行排序。 (我現在不想使用像std :: sort()這樣的函數)。用於迭代器的C++模板構造函數

std::deque<int> d; d.push_back(2); d.push_back(1); 
SortedContainer<int> sc1(d.begin(), d.end()); 

SortedContainer類,我想創建一個拷貝構造函數,處理該容器的迭代器(d.begin()和d.end())。

但是,如果我創建另一種類型的STL容器,我想要做同樣的事情。

std::vector<int> v; v.push_back(2); d.push_back(1); 
SortedContainer<int> sc2(v.begin(), v.end()); 

在這種情況下,我使用std :: vector而不是std :: deque。所以基本上,這將是一個模板構造函數。

template <class T> 
class SortedContainer 
{ 
    //... 
public: 
SortedContainer(template_iterator begin, template_iterator end) 
{ 
    //... 
} 
}; 

我知道,如果我加入類template_iterator作爲模板參數,它會很好地工作。

SortedContainer<int, std::deque::const_iterator> sc1(d.begin(), d.end()); 

但我不希望實例化SortedContainer類時告訴集裝箱的類型。我想通過container.begin()container.end()傳遞給它的構造函數。

我已經嘗試過使用std :: function和其他類型的方法,但都沒有工作。

+2

一種方式是寫一個'make_SortedContainer()'實用*功能*,以使編譯器可以推斷類型;以'std :: make_pair <>()'爲例。 –

回答

3

不是將模板添加到類中,而是可以使該函數成爲模板。

template <class T, class template_iterator> 
class SortedContainer 
{ 
    //... 
public: 
    SortedContainer(template_iterator begin, template_iterator end) 
    { 
     //... 
    } 
}; 

變爲

template <class T> 
class SortedContainer 
{ 
    //... 
public: 
    template <typename Iterator> 
    SortedContainer(Iterator begin, Iterator end) 
    { 
     //... 
    } 
}; 

所以,現在的功能狀態之外的任何類型,但您使用的名稱Iterator到該類型有望成爲一個迭代器自身的文件。請注意,由於這是一個構建的SOP,因此它應該受到SFINAE的限制,因此它不會過於寬泛。

2

您可以創建一個make_sorted_container函數,它扣爲您提供:

template <typename TContainer> 
auto make_sorted_container(TContainer&& c) 
{ 
    using element_type = std::decay_t<decltype(*std::begin(c))>; 
    using iterator_type = decltype(std::begin(c)); 

    return SortedContainer<element_type, iterator_type>(std::begin(c), std::end(c)); 
} 

可以使用如下:

std::vector<int> v; 
auto sv = make_sorted_container(v); 

static_assert(std::is_same< 
    decltype(sv), 
    SortedContainer<int, typename std::vector<int>::iterator> 
>{}); 

wandbox example


在C++ 17,class template deduction將允許模板參數由構造函數。在這種情況下,你需要一個扣除指南

template <class T, class TItr> 
class SortedContainer 
{ 
    //... 
public: 
    SortedContainer(TItr b, TItr e)    
    { 
     //... 
    } 
}; 

// Deduction guide: 
template <class TItr> 
SortedContainer(TItr b, TItr e) 
    -> SortedContainer<std::decay_t<decltype(*b)>, TItr>; 

可以使用這樣的:

std::vector<int> v; 
SortedContainer sv(v.begin(), v.end()); 

wandbox example

1

我會假設你的內部整理的表示排序容器不是取決於用於初始化它的容器的類型。然後,所有你需要做的是模板的構造:

template <typename Iter> 
SortedContainer(Iter first, Iter last) 
{ 
    //... 
}