Шаблон, содержащий итераторы коллекции std

Этот шаблон может хранить векторные итераторы определенного типа.

template<typename T>
struct foo
{
  typedef typename std::vector<T>::iterator it;

  std::vector<it> m_collection;
};

Как сделать шаблон более универсальным и поддерживать другие итераторы коллекции std (std::list, std::deque так далее)?

2 ответа

Решение

Как сделать шаблон более универсальным и поддерживать другие итераторы коллекции std (list, deque и т. Д.)?

Вы хотите передать контейнеры в качестве аргументов шаблона?

То есть: вы ищете аргументы шаблона-шаблона?

template <template <typename...> class C, typename T>
struct foo
{
  typedef typename C<T>::iterator it;

  std::vector<it> m_collection;
};

Можно использовать следующим образом

foo<std::vector, int>  fvi;
foo<std::set, long>    fsl;

Или, может быть

template <template <typename...> class C, typename ... Ts>
struct foo
{
  typedef typename C<Ts...>::iterator it;

  std::vector<it> m_collection;
};

Таким образом, вы можете использовать его также для карт?

foo<std::map, int, std::string>      fmis;
foo<std::unordered_map, long, char>  fulc;

К сожалению, это решение несовместимо с std::array, которые требуют аргумента не-шаблона.

Или, может быть, вы хотите передать тип и выбрать контейнер и содержащий тип, как через специализацию?

template <typename>
struct foo;

template <template <typename...> class C, typename ... Ts>
struct foo<C<Ts...>>
{
  typedef typename C<Ts...>::iterator it;

  std::vector<it> m_collection;
};

Таким образом, вы можете использовать его следующим образом

foo<std::vector<int>>                fvi;
foo<std::set<long>>                  fsl;
foo<std::map<int, std::string>>      fmis;
foo<std::unordered_map<long, char>>  fulc;

а также добавить специализацию для std::array

template <template <typename, std::size_t> class A,
          typename T, std::size_t N>
struct foo<A<T, N>>
{
  typedef typename A<T, N>::iterator it;

  std::vector<it> m_collection;
};

Или, может быть, просто

template <typename T>
struct foo
{
  typedef typename T::iterator it;

  std::vector<it> m_collection;
};

без выведения контейнера и содержимого типа?

Вот минимальный бегущий пример, где foo может переключаться между контейнерами последовательности для хранения it:

#include <vector> 
#include <deque> 
#include <list> 

template
<
    typename T, 
    template<typename, typename> class SequenceContainer,
    template <typename> class Allocator = std::allocator
>
struct foo
{
    typedef typename SequenceContainer<T, Allocator<T>>::iterator it;

    SequenceContainer<it, Allocator<it>> m_collection;
};

using namespace std; 

int main()
{
    foo<double, vector> vecFoo; 
    foo<double, deque>  dequeFoo; 
    foo<double, list>   listFoo; 

    return 0;
};
Другие вопросы по тегам