Question

J'ai obtenu des objets qui reposent sur différentes fonctions. Pour le dire en différents mots: il existe plusieurs types de fonctions sur lesquelles les variables de l'objet reposent, mais il devrait y avoir plusieurs objets avec la même chose de ces fonctions. Pour plus d'autorisation, j'ai essayé de donner un exemple (ce qui ne fonctionne pas).

#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;
}

C'est bien sûr un exemple minimal. La taille variable dépend d'une certaine fonction qui doit être transmise comme argument à la classe. Imaginer fun1 et fun2 comme différents types de générateurs de nombres aléatoires.

Je pense que la manière idéomatique en C ++ serait une classe qui contient la variable et que les classes héritées sont modifiées par cette fonction qui diffère les objets (veuillez me corriger si je me trompe avec cette hypothèse). Mais ma question est:

Y a-t-il une possibilité de mettre en œuvre une sorte de constructeur d'ordre supérieur? Si c'est le cas, un exemple serait bien.

PS: Si j'utilisais des termes techniques mal, je serais heureux d'être corrigé.

Était-ce utile?

La solution

Changer pour:

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

Et:

A a = A( fun1 );

Quand tu passais &fun1() Cela essayait d'appeler la fonction, puis de prendre l'adresse de son résultat. Ce que vous vouliez réellement, c'était le pointeur de fonction lui-même qui est stocké fun1.

Autres conseils

Cet exemple n'a pas de sens, car vous n'enregistrez pas le pointeur de fonction pour une utilisation ultérieure. Vous pouvez réécrire cela simplement pour simplement

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;
}

Je suggère d'écrire un modèle à la place afin que vous puissiez passer dans n'importe quel pointeur de fonction ou objet de fonction. Cela permet au compilateur de faire plus facilement des optimisations comme l'inclinaison dans de nombreux cas, et est plus flexible. Vous ne devez pas non plus utiliser des parenthèses lors de l'acquisition d'un pointeur de fonction.

#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;
}

On dirait que vous n'avez besoin que de la fonction elle-même à passer. Vous l'avez presque. Voici la syntaxe correcte:

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.

Vous pouvez également déclarer Foo comme suit:

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

Les fonctions ne sont pas des objets de première classe en C ++, donc la seule façon de créer une fermeture avec certaines variables (par exemple, si vous souhaitez porter la fonction ou appeler une fonction membre non statique) est les fonds (objets avec opérateur surchargé () ). Il existe plusieurs façons d'obtenir un tel objet:

  1. Définissez-le par vous-même, stockez toutes les variables nécessaires dans les champs et passez-la comme argument de la fonction.
  2. Utilisez les fonctions lambda de C ++ 11 et la fonction STD ::
  3. Utilisez Boost :: Fonction et Boost :: Bind.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top