c++ function templates stl c++14

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); }