简体   繁体   English

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

[英]C++ template constructor for iterators

I want to create different types of containers, and I want to sort them with my SortedContainer class. 我想创建不同类型的容器,并想用我的SortedContainer类对它们进行排序。 (I don't want to use functions like std::sort() now). (我现在不想使用类似std :: sort()的函数)。

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

In the SortedContainer class, I want to create a copy constructor, that handles the iterators of the containers (d.begin() and d.end()). SortedContainer类中,我想创建一个复制构造函数,该构造函数处理容器的迭代器(d.begin()和d.end())。

But if I create another type of container of STL, I want to do the same. 但是,如果我创建另一种STL容器,我也想这样做。

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

In this case, I'm using std::vector instead of std::deque. 在这种情况下,我使用的是std :: vector而不是std :: deque。 So basically, it would be a template constructor. 因此,基本上,它将是模板构造函数。

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

I know if I added class template_iterator as a template parameter, it would work well. 我知道如果我将class template_iterator添加为模板参数,它将很好地工作。

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

But I don't want to tell the containers' type when instantiating the SortedContainer class. 但是我不想在实例化SortedContainer类时告诉容器的类型。 I want to find it out when passing container.begin() and container.end() to its constructor. 我想在将container.begin()container.end()传递给其构造函数时发现它。

I have already tried using std::function and some other kind of methods, but none of them worked. 我已经尝试过使用std :: function和其他方法,但是它们都不起作用。

Instead of adding the template to the class you can make the function a template. 可以将函数设为模板,而不是将模板添加到类中。

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

Becomes

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

So now the function will except any type but you use the name Iterator to self document that the type is expected to be an iterator. 因此,现在该函数将排除任何类型,但您使用名称Iterator来自我证明该类型应为迭代器。 Do note that since this is a constructed SOP says that it should be constrained with SFINAE so it is not overly broad. 请注意,由于这是一个构造好的SOP,因此应将其与SFINAE一起使用,因此它不会过于宽泛。

You can create a make_sorted_container function that does the deduction for you: 您可以创建一个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));
}

It can be used as follows: 可以如下使用:

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 魔盒示例


In C++17, class template deduction will allow template arguments to be deduced by constructors. 在C ++ 17中, 类模板推导将允许构造函数推导模板参数。 In this case you need a deduction guide : 在这种情况下,您需要一个演绎指南

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>;

Can be used like this: 可以这样使用:

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

wandbox example 魔盒示例

I'm going to assume that the internal sorted representation of your sorted container does not depend on the type of the container used to initialize it. 我将假设已排序容器的内部已排序表示形式取决于用于初始化它的容器的类型。 Then all you need to do is template the constructor: 然后,您需要做的只是模板构造器:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM