Pointers in C++
This post focus in pointers c++ 17 and beyond…
-
template
class CountCalls → Se crea el template CB para la clase template CountCalls. Clase template CountCalls del tipo CB. -
CountCalls(CB cb) : callback(cb) {} → Constructor CountCalls que recibe tipo CB para luego transferir el valor cb a callback mediante la instruccion “:callback(cb)”. Un puntero a una funcion de un tipo abstracto CB.
-
decltype(auto) operator() (Args&&… args){..} → Metodo template que sobrecarga el operador () que recibe un paquete de argumentos y retorna callback( … ) que es una puntero a una funcion igual a cb(print) con los argumentos desempaquetados
-
(… args) → si “…” estan a la izquierda, son argumentos empaquetados. Un paquete de parametros.
-
(args …) → si “…” estan a la derecha, son argumentos desempaquetados. Un paquete de parametros expandidos.
-
return callback(forward
(args)…); → llama al puntero a la funcion cb(print) y tienen como arguemntos el paquete desempaquetado. -
decltype(auto) → Indica el tipo de dato de auto. Lo hace mas dinamico.
template<typename CB>
class CountCalls
{
private:
CB callback; // callback to call
long calls = 0; // counter for calls
public:
CountCalls(CB cb) : callback(cb) {}
template<typename... Args> // Metodo template dentro de una clase template.
decltype(auto) operator() (Args&&... args)
{ ++calls;
return callback(forward<Args>(args)...);
}
auto count() const { return calls; }
};
print es una funcion que recibe un vector de enteros por referencia y devuelve un float:
float print(const vector<int>& coll)
{
cout << "elems: ";
for (const auto& elem : coll)
{ cout << elem << ' '; }
cout << '\n';
return 0.0;
}
Idem. TestFn funcion de prueba.
void TestFn(int x, float f, string str)
{
cout << "x = " << x << " f = " << f << " str: " << str << endl;
}
Para probar CountCalls, se creoa DemoCallBack():
CountCalls cb(print); → genera un objeto del tipo CountCalls llamado cb que recibe como parametro la funcion(recordar: pasar una funcion significa pasar un puntero a la funcion, es decir su direccion) print que es guardado en la variable CB callback. CountCalls cc(TestFn);→ idem
cb(vals); → sobrecarga de operator() al objeto cb con el argumento vals que lo que hace al final es aumentar la variable long ++calls y retornar el puntero a la funcion print(vals) con vals desempaquetado. cc(3,6.6,“hi”); → idem
void DemoCallBacks()
{
vector<int> vals{0, 8, 15, 42, 13, -1, 0};
CountCalls cb(print);
cb(vals);
cb(vals);
cout << "CountCalls=" << cb.count() << endl;
CountCalls cc(TestFn);
cc(3,6.6,"hi");
}
Resultado:
>>>>>>>>>>>>> DemoCallBacks() ...
elems: 0 8 15 42 13 -1 0
elems: 0 8 15 42 13 -1 0
CountCalls=2
x = 3 f = 6.6 str: hi