Domanda

Ho ottenuto alcuni oggetti che le variabili si basano su funzioni diverse. Per metterlo in parole diverse: ci sono più tipi di funzioni su cui si basano le variabili nell'oggetto, ma dovrebbero esserci più oggetti con gli stessi di queste funzioni. Per ulteriori autorizzazioni ho cercato di fare un esempio (che non funziona).

#include <iostream>

class A
{
  double size;

  A( double (*f)() )
  {
    size = (*f)();
  };
};

double fun1()
{
  return 42.0;
}


int main()
{
  A a = A( &fun1() );

  std::cout << a.size << std::endl;
}

Questo è ovviamente un esempio minimo. La dimensione variabile dipende da una determinata funzione che dovrebbe essere passata come argomento alla classe. Immaginare fun1 e fun2 come diversi tipi di generatori di numeri casuali.

Penso che il modo ideomatico in C ++ sarebbe una classe che contiene la variabile e le classi ereditate da essa siano modificate da quella funzione che differisce gli oggetti (per favore correggimi se sbaglio con questo presupposto). Ma la mia domanda è:

Esiste la possibilità di implementare una sorta di costruttore di ordine superiore? In tal caso, un esempio sarebbe bello.

PS: se usassi alcuni termini tecnici sbagliati, sarei felice di essere corretto.

È stato utile?

Soluzione

Cambiare in:

A( double (*f)() )
{
    size = f();
};

E:

A a = A( fun1 );

Quando stavi passando &fun1() Questo stava cercando di chiamare la funzione e poi prendere l'indirizzo del suo risultato. Quello che in realtà volevi era il puntatore della funzione stesso che è memorizzato fun1.

Altri suggerimenti

Questo esempio non ha senso, perché non si salva il puntatore della funzione per un uso successivo. Puoi riscriverlo semplicemente a

class A
{
    double size;

    A(double sz) {
        size = sz;
    };
};

double fun1()
{
    return 42.0;
}


int main()
{
    A a = A(fun1());
    std::cout << a.size << std::endl;
}

Suggerisco invece di scrivere un modello in modo da poter passare in qualsiasi puntatore o oggetto funzione di funzione. Ciò consente al compilatore di eseguire più facilmente ottimizzazioni come in linea di livello ed è più flessibile. Inoltre, non dovresti usare parentesi durante l'acquisizione di un puntatore della funzione.

#include <iostream>

class A {
public:
    template<typename F>
    explicit A(F&& f) : size(f()) {

    };

    double size;
};

double fun1() {
    return 42.0;
}

int main() {
    A a(&fun1);
    std::cout << a.size << std::endl;
}

Sembra che tu abbia bisogno solo della funzione stessa da passare. Ce l'hai quasi. Ecco la sintassi corretta:

typedef double (*functype)();

void foo(functype f) {
    cout << f();
}

double bar() {
    return 2.39;
)

foo(bar); // don't call bar here, just pass it as address.

Puoi anche dichiarare Foo come segue:

void foo(double (*f)());

Le funzioni non sono oggetti di prima classe in C ++, quindi l'unico modo per creare una chiusura con alcune variabili (ad esempio, se si desidera trasportare la funzione o chiamare una funzione membro non statica) è funttori (oggetti con operatore sovraccarico () ). Esistono diversi modi per ottenere tale oggetto:

  1. Definiscilo da solo, memorizza tutte le variabili necessarie nei campi e passalo come argomento della funzione.
  2. Usa le funzioni Lambda di C ++ 11 e la funzione std ::
  3. Usa boost :: function and boost :: bind.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top