Я пытаюсь реализовать функцию, аналогичную алгоритму std::transform
, но вместо того, чтобы принимать выходной итератор аргументом, я хочу создать и вернуть контейнер с преобразованными элементами ввода.
Скажем, что он называется transform_container
и принимает два аргумента: container и functor. Он должен возвращать один и тот же тип контейнера, но, возможно, параметризован другим типом элемента (Functor может возвращать элемент другого типа).
Я хотел бы использовать свою функцию, как в примере ниже:
std::vector<int> vi{ 1, 2, 3, 4, 5 };
auto vs = transform_container(vi, [] (int i) { return std::to_string(i); });
//vs will be std::vector<std::string>
assert(vs == std::vector<std::string>({"1", "2", "3", "4", "5"}));
std::set<int> si{ 5, 10, 15 };
auto sd = transform_container(si, [] (int i) { return i / 2.; });
//sd will be of type std::set<double>
assert(sd == std::set<double>({5/2., 10/2., 15/2.}));
Мне удалось написать две функции - одну для std::set
и одну для std::vector
- которые, похоже, работают правильно. Они идентичны, за исключением имени контейнера. Их код указан ниже.
template<typename T, typename Functor>
auto transform_container(const std::vector<T> &v, Functor &&f) -> std::vector<decltype(f(*v.begin()))>
{
std::vector<decltype(f(*v.begin()))> ret;
std::transform(std::begin(v), std::end(v), std::inserter(ret, ret.end()), f);
return ret;
}
template<typename T, typename Functor>
auto transform_container(const std::set<T> &v, Functor &&f) -> std::set<decltype(f(*v.begin()))>
{
std::set<decltype(f(*v.begin()))> ret;
std::transform(std::begin(v), std::end(v), std::inserter(ret, ret.end()), f);
return ret;
}
Однако, когда я попытался объединить их в одну общую функцию, которая работает с любым контейнером, я столкнулся с многочисленными проблемами. set
и vector
являются шаблонами классов, поэтому мой шаблон функции должен принимать параметр шаблона шаблона. Более того, набор и векторные шаблоны имеют различное количество параметров типа, которые необходимо правильно настроить.
Каков наилучший способ обобщения двух шаблонов функций выше в функцию, которая работает с любым совместимым типом контейнера?