Utilizando el reenvío perfecto en el predicado de STL
¿Tiene sentido usar un reenvío perfecto en algunos algoritmos de STL? ¿Cuál será el tipo deducido?
auto it = std::find_if(cont.cgebin(),
cont.cend(),
[](auto&& element){ return myFunction(std::forward<decltype(element)>(element)); })
Supongo que se usará la versión de valor L (¿y qué pasa con const?), pero ¿qué determina eso? ¿Existen otros algoritmos que envíen un valor de valor R? No lo creo, porque significaría que el predicado podría “consumir” el elemento, independientemente del resultado del predicado.</decltype(element)>
davy.ai
Sí, tiene sentido utilizar reenvío perfecto en algunos algoritmos de STL, como el ejemplo dado con
std::find_if
. El tipo deducido dependerá del tipo del contenedor “cont” y del tipo de sus elementos. Dado que el tipo de elemento se pasa comodecltype(element)
astd::forward
, el tipo deducido será el mismo que el tipo del elemento.En este caso, la función lambda utiliza reenvío perfecto para preservar la categoría de valor de “element”, que puede ser un lvalue o un rvalue, dependiendo del tipo de “cont” y de cómo se pasó a
std::find_if
. Esto permite que la funciónmyFunction
reciba la categoría de valor de “element” que originalmente se pasó astd::find_if
, sin ninguna copia o movimiento innecesario.En cuanto a “const”, eso depende del tipo de “cont”. Si “cont” tiene una calificación de const, entonces
cont.cbegin()
ycont.cend()
devolveránconst_iterator
, y la función lambda recibirá una referencia const cualificada a “element”.Puede haber otros algoritmos de STL que podrían enviar un rvalue, pero tendrían que diseñarse cuidadosamente para evitar el problema que mencionaste sobre consumir el elemento. Por ejemplo,
std::move_if_noexcept
utiliza una referencia a un rvalue para determinar si un objeto se puede mover sin lanzar una excepción, pero está diseñado para mover el objeto solo si es seguro hacerlo.