迭代器的 C++ 模板构造函数

dud*_*ace 3 c++ stl

我想创建不同类型的容器,并且想使用SortedContainer类对它们进行排序。(我现在不想使用像 std::sort() 这样的函数)。

std::deque<int> d; d.push_back(2); d.push_back(1);
SortedContainer<int> sc1(d.begin(), d.end());
Run Code Online (Sandbox Code Playgroud)

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());
Run Code Online (Sandbox Code Playgroud)

在本例中,我使用 std::vector 而不是 std::deque。所以基本上,它将是一个模板构造函数。

template <class T>
class SortedContainer
{
   //...
public:
 SortedContainer(template_iterator begin, template_iterator end)
 {
   //...
 }
};
Run Code Online (Sandbox Code Playgroud)

我知道如果我添加类 template_iterator作为模板参数,它会很好地工作。

SortedContainer<int, std::deque::const_iterator> sc1(d.begin(), d.end());
Run Code Online (Sandbox Code Playgroud)

但我不想在实例化SortedContainer类时告诉容器的类型。我想在将container.begin()container.end()传递给它的构造函数时找到它。

我已经尝试过使用 std::function 和其他一些方法,但它们都不起作用。

Vit*_*meo 5

您可以创建一个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));
}
Run Code Online (Sandbox Code Playgroud)

它可以按如下方式使用:

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

static_assert(std::is_same<
    decltype(sv), 
    SortedContainer<int, typename std::vector<int>::iterator>
>{});
Run Code Online (Sandbox Code Playgroud)

魔杖盒示例


在 C++17 中,类模板推导将允许构造函数推导模板参数。在这种情况下,您需要一份扣除指南

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>;
Run Code Online (Sandbox Code Playgroud)

可以这样使用:

std::vector<int> v;
SortedContainer sv(v.begin(), v.end());
Run Code Online (Sandbox Code Playgroud)

魔杖盒示例