Expresiones lambda frente a punteros de función

Puntero de función: Un puntero de función , o un puntero de subrutina, o un puntero de procedimiento, es un puntero que apunta a una función . En palabras simples, es un puntero a la ubicación dentro de la sección de texto. Almacena la dirección de una función y se usa para pasar un comportamiento como parámetro a otra función.

Por ejemplo, si alguien quiere ordenar un contenedor como un vector o listas, y usa STL sort() , pero no desea ordenarlo en orden ascendente, que es el parámetro predeterminado, en ese caso, pase un comportamiento a la función de clasificación , que en realidad es el puntero de la función, y ordenar sus datos.

Programa 1: A continuación se muestra el programa C++ para implementar el concepto anterior:

C++

// C++ program to implement the above
// concepts
#include <bits/stdc++.h>
using namespace std;
 
// Descending order sorting function
int descending(int x, int y)
{
    return x > y;
}
 
// Absolute value sorting function
int absolute(int x, int y)
{
    return abs(x) > abs(y);
}
 
// Driver Code
int main()
{
    // Stores integers in the vector
    vector<int> vect = { 2, 8, -5, -9,
                         0, 12, 5 };
 
    cout << "Sorting with descending "
         << "order as parameter\n";
 
    // Stores the address of descending
    // order function in the funnptr
    // function pointer
    auto funptr = descending;
 
    // Pass pointer in the actual function
    sort(vect.begin(), vect.end(), funptr);
 
    // Print the vector
    for (auto i : vect)
        cout << i << " ";
 
    cout << "\n";
 
    cout << "Sorting with absolute order"
         << " as parameter \n";
 
    // Store the address of the absolute
    // value function in the funnptr1
    // function pointer
    auto funptr1 = absolute;
 
    // Pass pointer in actual function
    sort(vect.begin(), vect.end(), funptr1);
 
    // Print the vector
    for (auto i : vect) {
        cout << i << " ";
    }
 
    return 0;
}
Producción: 

Sorting with descending order as parameter
12 8 5 2 0 -5 -9 
Sorting with absolute order as parameter 
12 -9 8 5 -5 2 0

 

¿Por qué necesitamos punteros de función? Un puntero de función se utiliza para los siguientes propósitos:

  • Puede almacenar la dirección de una función.
  • Al igual que los punteros normales, un puntero de función se puede pasar a una función.
  • Se puede usar en qsort() , una función de biblioteca de programación C para clasificar, así como sort(), una función de biblioteca STL de C++ para clasificar.
  • Se puede utilizar para implementar funciones virtuales .

Programa 2: a continuación se muestra el programa C++ para llamar a una función sin parámetros o una función que tiene dos parámetros usando un puntero de función:

C++

// C++ program to implement the above
// concepts
#include <iostream>
using namespace std;
 
// Function having no parameter
void fun()
{
    cout << "GeeksforGeeks\n";
}
 
// Function having two parameters
// and a return type
int add(int x, int y)
{
    return x + y;
}
 
// Driver Code
int main()
{
    // Function pointer declaration
    // for a function having no *
    // return type and no parameter
 
    // note that this is the standard
    // syntax used for declaring a
    // function pointer
    void (*funptr)() = fun;
 
    // auto funptr = fun; can also be
    // used
 
    // Calling the function pointer
    funptr();
 
    cout << "\n";
 
    // Function pointer declaration
    // for a function having int as
    // return type and two int parameter
 
    int (*funptr1)(int, int) = add;
 
    // Calling the function pointer
    int x = funptr1(4, 6);
    cout << x;
 
    return 0;
}
Producción: 

GeeksforGeeks

10

 

Expresiones lambda: las expresiones lambda se introdujeron en C++11 . La razón detrás de la introducción de esto fue eliminar la complejidad o la incomodidad que se enfrentaba al usar el puntero de función. Para usar punteros de función, es necesario crear una función separada. Después de eso, cree un puntero de función a esa función y luego páselo como un parámetro a la función requerida.

Como las tareas realizadas mediante el uso de punteros de función son muy pequeñas, no vale la pena escribir tantas líneas de código. Por lo tanto, las expresiones lambda facilitan hacer el mismo trabajo.

Una expresión Lambda también se denomina función anónima. Es una expresión contenida dentro de la función principal y ayuda al pasar un comportamiento como parámetro a una función. En el caso predeterminado, no tiene acceso a ninguna de las variables presentes dentro de la función principal. Para acceder a ellas, es necesario realizar algunas modificaciones en la lista de captura de las expresiones.

Sintaxis:

[lista de capturas](parámetros) -> {
        // Cuerpo
};

Construcciones de una expresión Lambda: 

  • [ ]: lista de capturas
  • ( ): parámetro
  • ->: flecha
  • .: tipo de devolución
  • { }: cuerpo de la función

Programa 3: a continuación se muestra el programa que ilustra cómo se pueden usar las expresiones lambda para clasificar en orden descendente y con valores absolutos.

C++

// C++ program to illustrate the
// above concept
#include <bits/stdc++.h>
using namespace std;
 
// Driver Code
int main()
{
    vector<int> vect{ -1, -6, 4, 2, 0,
                      6, 3, 9, -5 };
 
    cout << "Before sorting : \n";
    for (auto i : vect) {
        cout << i << " ";
    }
 
    cout << "\n";
 
    cout << "Sorting in descending "
         << "order \n";
    sort(vect.begin(), vect.end(),
         [](int a, int b) {
             return a > b;
         });
 
    for (auto i : vect)
        cout << i << " ";
 
    cout << "\n";
 
    cout << "Sorting with absolute "
         << "value as parameter\n ";
    sort(vect.begin(), vect.end(),
         [](int a, int b) {
             return abs(a) > abs(b);
         });
 
    for (auto i : vect)
        cout << i << " ";
 
    cout << "\n";
 
    return 0;
}
Producción

Before sorting : 
-1 -6 4 2 0 6 3 9 -5 
Sorting in descending order 
9 6 4 3 2 0 -1 -5 -6 
Sorting with absolute value as parameter
 9 6 -6 -5 4 3 2 -1 0 

Nota: Al escribir una expresión lambda, de forma predeterminada, no habrá acceso a las variables en las que se escribe la expresión. Entonces, para obtener acceso a esas variables, es necesario realizar los siguientes cambios en la lista de captura de las expresiones lambda.

Lista de captura en la expresión Lambda:

  • [ ]: no captura nada.
  • [ = ]: captura todo por valor. Sólo da acceso de lectura.
  • [ & ]: captura todo por referencia. Da acceso de lectura y escritura.
  • [ =, & x]: captura todo por valor y x variable por referencia.
  • [ =x, & ]: captura todo por referencia y x por valor.

Programa 4: A continuación se muestra el programa para ilustrar el uso de una lista de captura:

C++

// C++ program to illustrate the above
// concept
#include <iostream>
using namespace std;
 
// Driver Code
int main()
{
    int x = 0, a = 5, b = 4;
 
    // In the below lambda expression,
    // everything is captured by value,
    // and only x by reference
    auto fun = [=, &x](int x) {
 
        // If one tries to manipulate
        // the value of a read only
        // variable, then it causes
        // a compilation error.
        x++;
 
        // c is a new variable under
        // the fun expression which
        // sums up a and b
        int c = a + b;
 
        cout << "sum of the read only "
             << "variables is : " << c
             << "\n";
 
        return x;
    };
 
    cout << "The value of x is " << fun(x);
 
    return 0;
}
Producción: 

sum of the read only variables is : 9
The value of x is 1

 

Este artículo es una contribución de Kartik Suman .

Publicación traducida automáticamente

Artículo escrito por sumankartik8 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *