Допустим есть функция (что-то вроде std::transform), которая принимает на входе контейнер (либо vector, либо list, либо deque) содержащий элементы типа Х и функцию, которая, в свою очередь, принимает тип Х и возвращает тип Y. На выходе получаем контейнер содержащий элементы типа Y. Вопрос заключает в том, как это лучше реализовать (в плане удобства пользования)?
1. Не важно какой контейнер на входе — всегда возвращать определенный контейнер (например vector):
template<template<class...> class input_sequence, class T, class functor>
std::vector<typename std::result_of<functor(T)>::type> foo(const input_sequence<T>& sequence, functor func)
{
std::vector<typename std::result_of<functor(T)>::type> result;
...
return result;
}
double bar(int x)
{
return sqrt(x);
}
std::vector<int> in{1, 2, 3, 4, 5};
auto out = foo(in, bar);
2. Возвращать контейнер того же типа, что и контейнер на входе:
template<template<class...> class input_sequence, class T, class functor>
input_sequence<typename std::result_of<functor(T)>::type> foo(const input_sequence<T>& sequence, functor func)
{
input_sequence<typename std::result_of<functor(T)>::type> result;
...
return result;
}
double bar(int x)
{
return sqrt(x);
}
std::vector<int> in{1, 2, 3, 4, 5};
auto out = foo(in, bar);
3. Явно инстанцировать шаблон:
template<class output_sequence, class input_sequence, class functor>
output_sequence foo(const input_sequence& sequence, functor func)
{
output_sequence result;
...
return result;
}
double bar(int x)
{
return sqrt(x);
}
std::vector<int> in{1, 2, 3, 4, 5};
auto out = foo<std::vector<double>>(in, bar);
За изобретение костылей прошу сильно не пинать!