es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo crear un espacio de nombres similar a una plantilla para funciones miembro.

Actualmente estoy tratando de definir un espacio de nombres/estructura que contiene punteros a funciones que almacenan implementaciones específicas (digamos una estructura para contener varias funciones). Por ahora todo funciona bien con la siguiente estructura:

class foo{
    int a;
    int b;

public:
    explicit foo(int _a, int _b) : a(_a), b(_b) {};
    std::function<int(int)> bar(int num) = [=](int num) -> int{
         // aquí necesito conocer a y b
         // hacer algo con num y retornar
    }
}

Esta clase contiene varias funciones donde cada una tiene que conocer a y b. El problema es que tengo que crear una instancia de la clase y establecer los parámetros a y b, lo cual preferiría omitir.
En otra clase, solo utilizo las funciones de esta clase. Es decir,

class foo2{
    // algunos otros parámetros
    int a, b;
    std::function<...> fun1, fun2,...;
public:
    foo2(int a, int b, ....){this->a = a; this->b = b;};
    setFuncs(){
        foo instance(a, b); 
        this->fun1 = [instance](int num){ return instance.bar(num);}
        this->fun2 = ...
    }
}

pero quiero omitir crear una nueva instancia de la clase cada vez (en el sentido de que repito el comportamiento anterior en la misma clase pero en otro lugar del código). Intenté hacer plantillas con esta clase como

template<int a,="" int="" b="">
class foo{
...
}

así que podría asignar las funciones como:

this->fun1 = foo<a,b>::bar;

Pero luego necesitaría conocer a y b en tiempo de compilación, lo cual no es posible. Esos parámetros se establecen una vez en la clase foo2. Me doy cuenta de que el código general puede no estar limpio, soy físico, no informático, como puedes ver. Una forma sería almacenar una instancia de la clase foo en la clase foo2 e inicializarla una vez para toda la clase y permitir que las funciones fun1, fun2,… tengan acceso por referencia a esos punteros, pero estoy buscando si hay otra forma (quizás una clase como plantilla, donde no necesite conocer los valores en tiempo de compilación).
Además, no puedo pegar todo el código aquí porque contiene miles de líneas en varios archivos y describir lo que hace el código es muy difícil. Agradezco cualquier ayuda y me disculpo si esta puede ser una pregunta estúpida o trivial (no trabajo estrictamente en informática, soy físico 😉 )</a,b></int(int)>

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece que quieres evitar crear múltiples instancias de foo en tu código y quieres poder establecer los valores de a y b dinámicamente. Una forma de lograr esto es usar una variable estática dentro de la clase foo para almacenar los valores de a y b, y luego usar una función miembro estática para establecer esos valores cuando creas la primera instancia de foo.

    Aquí tienes un ejemplo:

    class foo {
        static int a;
        static int b;
    
    public:
        explicit foo() = default;
        static void set_values(int _a, int _b) {
            a = _a;
            b = _b;
        }
        static std::function<int(int)> bar(int num) {
            // aquí podemos usar a y b
            return [=](int num) -> int {
                // hacer algo con num y retornar
            };
        }
    };
    
    int foo::a = 0;
    int foo::b = 0;
    
    class foo2 {
        int a, b;
        std::function<int(int)> fun1, fun2;
    public:
        foo2(int _a, int _b): a(_a), b(_b) {
            foo::set_values(a, b);
            fun1 = foo::bar(42);
            fun2 = foo::bar(17);
        }
    };
    

    En este ejemplo, usamos variables estáticas a y b dentro de foo, lo que significa que solo hay una copia de estas variables compartida por todas las instancias de foo. También agregamos una función miembro estática set_values que establece los valores de a y b para la clase.

    En tu clase foo2, cuando creas una instancia de foo, llamas a foo::set_values(a, b) para establecer los valores de a y b, y luego llamas a foo::bar para crear los objetos std::function para fun1 y fun2.

    Ten en cuenta que en este ejemplo, asumimos que fun1 y fun2 siempre utilizarán los mismos valores de a y b, que se establecen en el constructor de foo2. Si necesitas cambiar estos valores más tarde, puedes llamar nuevamente a foo::set_values con los nuevos valores.</int(int)></int(int)>

Comments are closed.