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

时间:2017-01-12 15:56:32

标签: c++ stl

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

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)
 {
   //...
 }
};

我知道如果我将 class template_iterator 添加为模板参数,它会很好用。

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

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

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

3 个答案:

答案 0 :(得分: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的约束,因此它不会过于宽泛。

答案 1 :(得分: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

答案 2 :(得分:1)

我将假设已排序容器的内部排序表示取决于用于初始化它的容器的类型。然后你需要做的就是模板化构造函数:

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