Предположим, я хочу реализовать общую функцию Map
более высокого порядка в C++. Map
должен взять контейнер и функцию преобразования и вернуть контейнер того же типа, но, возможно, с разными типами элементов.Ограничения на типы шаблонов
Давайте vector
, например:
template <typename InT, typename OutT, typename Tr>
vector<OutT> Map(vector<InT> cont, Tr tr)
{
OutCont out(cont.size());
auto oit = out.begin();
for (auto it = cont.cbegin(); it != cont.cend(); ++it, ++ot)
{
*oit = tr(*it);
}
}
, которые я хочу использовать так:
vector<int> v(10);
std::iota(v.begin(), v.end(), 0);
auto x = Map(v, [](int x) -> int {return x * 2;});
Это терпит неудачу в VC++ 2012, что дает мне следующую ошибку:
error C2783: 'std::vector<OutT> Map(std::vector<_Ty>,Tr)' : could not deduce template argument for 'OutT'
Мне кажется, что компилятор имеет всю необходимую информацию, потому что я явно определил тип возврата в лямбда. Есть ли способ обойти это?
В приведенном выше примере используется vector
. Есть ли способ использовать общий тип, чтобы типы ввода и вывода были одинаковыми? Например, если у меня есть контейнер ввода, определенный как vector<string>
и функция преобразования tr(string a) -> int
, тогда моя цель - заставить компилятор определить тип вывода vector<int>
. Вот псевдо-код для того, что я хочу добиться:
template <typename Cont<InT>, typename Cont<OutT>, typename Tr<InT, OutT>>
Cont<OutT> Map(Cont<InT> cont, Tr<InT, OutT> tr)
{
// Implementation
}
неродственных, но именовании функции 'map' немного сбивает с толку , заданный 'std :: map'. – juanchopanza
Функциональное программирование 'map' ==' std :: transform'. Итераторы действительно позволяют вам выполнять общее программирование над контейнерами в C++: используйте их. – Yuushi
Спасибо. Я изменил его на «Карта». Следует устранить путаницу. – Max