c++ - ¿Cómo proporcionar la firma de función para una función que toma iteradores de contenedores stl?
function templates (3)
¡La sintaxis no es
demasiado
oscura!
La siguiente forma usa el rango
for
en el punto de uso:
template <template<typename...> class Iterable, typename T>
void foo(
const Iterable<T>& y // the container
){
for (auto&& e : y){
// e is the ''thingy'' in the container.
}
}
y puede pasar cualquier contenedor iterable de tipo arbitrario a
foo
.
Quiero escribir una función
my_func
que se pueda llamar así, pero no me importa que
v
sea un
std::vector
, podría ser cualquier contenedor STL.
Un poco como
std::for_each
:
std::vector<std::string> v = {...};
my_func(v.begin(), v.end());
Pero no puedo entender la firma de la función.
void my_func(??? i1, ??? i2)
{
std::for_each(i1, i2, ...); // dumb example implementation
}
No soy bueno en la programación de plantillas, por lo que incluso mirar la declaración de función para
std::for_each
no me ayuda.
¿Existe una implementación fácil o esto se va a complicar fundamentalmente con los vars de plantillas?
Depende de cuán genérico desee que sea la función. Si los tipos de iterador tienen que coincidir, entonces
template <typename T>
void my_func(T i1, T i2)
{
std::for_each(i1,i2,...); //dumb example implementation
}
es todo lo que necesitas. Si desea que puedan ser diferentes, entonces solo necesita otro parámetro de plantilla como
template <typename T, typename U>
void my_func(T i1, U i2)
{
std::for_each(i1,i2,...); //dumb example implementation
}
Finalmente, si no le gusta tratar con plantillas, puede usar una lambda en su lugar y dejar que el compilador se encargue de esto por usted. Eso te daría
auto my_func = [](auto i1, auto i2)
{
std::for_each(i1,i2,...); //dumb example implementation
};
Podrías escribir una función con plantilla
template<typename Iterator>
void my_func(Iterator startIter, const Iterator endIter)
{
std::for_each(startIter, endIter, /* lambda */);
}
En caso de preguntarse, cómo pasar el tercer parámetro de
std::for_each
, podría proporcionar un parámetro de plantilla más
const auto defaultCallable = [](auto element){ }; // does nothing
template<typename Iterator, typename Callable = decltype(defaultCallable)>
void my_func(Iterator startIter, const Iterator endIter, Callable func = {})
{
std::for_each(startIter, endIter, func);
}