функция вложенных шаблонов, принимающая 2 контейнера с одинаковым внутренним типом - PullRequest
0 голосов
/ 27 сентября 2018

Я пытаюсь написать функцию, которая примерно похожа на функцию, которая принимает два экземпляра контейнеров (скажем, пока они одинаковые), содержит один и тот же тип и объединяет их.Итак, вот моя функция для векторов:

template<typename T>
void test(std::vector<T> v1, std::vector<T> v2) {
  std::cout << "called nested for c\n";
}

, и она работает.

Теперь я хочу иметь функцию, которая будет работать для множеств или векторов.И я пытаюсь это:

template<typename T, template <typename> typename C >
void test(C<T> v1, C<T> v2) {
  std::cout << "called nested for c<t>\n";
}

и получить

nestedt.cc: 33: 6: note: сбой вывода / замены аргумента шаблона: nestedt.cc:43:12:ошибка: неверное количество аргументов шаблона (3, должно быть 1) test (s, s);^ nestedt.cc:32:51: примечание: предоставляется для 'шаблона класса C' имя шаблона C> ^

Я пытаюсь

template< template <typename T> typename C >
void test(C<T> v1, C<T> v2) {}

std::set<int> s = {1,2};
test(s, s);

, и это не работает:

nestedt.cc: 32: 6: примечание: сбой вывода / замены аргумента шаблона: nestedt.cc:42:12: примечание: невозможно преобразовать 's' (тип 'std :: set')набрать 'int' test (s, s);^

Поэтому я пытаюсь

template<typename C, typename T >
void test(C<T> v1, C<T> v2) {}

и получаю

nestedt.cc: 32: 6: note :андидат: шаблон void test (C, C) void test (C v1, C v2) {^ nestedt.cc:32:6: note: сбой вывода / замены аргумента шаблона: nestedt.cc:42:12: note: не удалось вывести параметр шаблона 'T'тест (ы, с);^

Мне кажется, я даже близко не понимаю, как на самом деле работают шаблоны в C ++, и это так грустно.Также на самом деле я хочу, чтобы контейнеры были другими.И в идеале быть в состоянии как-то указать ограниченный набор разрешенных контейнеров.И они на самом деле не являются std :: Containers.

Обратите внимание, что конечная цель состоит в том, чтобы иметь возможность взять 2 разных контейнера, что-то вроде test(vector<int>, set<int>).И модификация контейнеров вроде невозможна.

Ответы [ 3 ]

0 голосов
/ 27 сентября 2018

Ваша первая попытка была почти правильной.Вы получили ошибку, потому что стандартные контейнеры, такие как vector, принимают более одного параметра шаблона.Например, это std::vector:

template<
    class T,
    class Allocator = std::allocator<T>
> class vector;

Обычно вы никогда не используете второй параметр, и он имеет значение по умолчанию, но он все еще присутствует, поэтому параметр шаблона вашего шаблона template <typename> typename C не может совпадать.Вместо этого вы можете сделать это:

template<template <typename...> typename C, typename... Ts>
void test(C<Ts...> v1, C<Ts...> v2) {}
0 голосов
/ 27 сентября 2018

Я считаю, что вы ищете

template<template <typename...> typename Cont1, 
         template <typename...> typename Cont2,
         typename... T>
void test(Cont1<T...> a, Cont2<T...> b) { }

В приведенном выше примере template <typename...> typename Cont1 объявляет один тип шаблона, а template <typename...> typename Cont2 объявляет другой, так что вы можете иметь два разных типа контейнера.Оба имеют общий T..., поэтому каждый контейнер шаблона должен иметь соответствующий список параметров шаблона.Это означает, что

test(std::map<int, int>{}, std::map<int, int>{});
test(std::set<int>{}, std::set<int>{});
test(std::vector<int>{}, std::set<int>{});

все работает, но

test(std::map<int, int>{}, std::vector<int>{});
test(std::map<int, int>{}, std::set<int>{});

не будет.

0 голосов
/ 27 сентября 2018

Вам нужно как минимум 2 параметра шаблона:

  1. Тип контейнера
  2. Содержащий тип

Поскольку вы используете контейнер STL и передавая содержащийся тип отдельно от контейнера , компилятор не может определить другие параметры (например, распределитель std::allocator<T>, сравнить std::less<T>).Но вы можете переслать все вложенные шаблонные параметры, используя шаблон переменной.Пример:

template <template <typename...> class C, typename... T>
struct wrapper {
    typedef C<T...> type;
};
wrapper<std::vector, int>::type foo;
wrapper<std::set   , int>::type bar;

Вы можете увидеть его в идеоне .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...