Question

Il y a un moment j'ai utilisé std::function à peu près comme ceci:

std::function<void(int)> func = [](int i) -> int { return i; };

En fait, je l'ai fait parce que je voulais stocker différents objets de fonction dans un std::function, mais je ne voulais pas limiter les types de retour de ces fonctions. Comme il semblait travailler, je suis allé avec lui. Mais je ne suis pas convaincu qu'il est sûr à utiliser, et je ne l'ai pas été en mesure de trouver toute la documentation à ce sujet. Est-ce que quelqu'un sait si cet usage est légitime? Ou plus généralement, quelles sont les règles pour l'objet qui peut en toute sécurité être affecté à un std::function?

Modifier

Pour plus de précisions, la question qui me préoccupe est que la fonction lambda retourne un int, alors que func est déclarée avec le type de retour void. Je ne sais pas si cela est OK, surtout une fois un appel à func() est fait.

Était-ce utile?

La solution

Votre code a un comportement non défini. Il peut ou peut ne pas fonctionner comme prévu. La raison pour laquelle il a un comportement non défini est à cause de 20.8.11.2.1 [func.wrap.func.con] / P7:

Nécessite: F doit être CopyConstructible. f est appelable (20.8.11.2) pour les types d'arguments ArgTypes et le type de retour R.

Pour f être rachetable pour le type de retour R, f doit retourner quelque chose implicitement convertible au type de retour du std::function (void dans votre cas). Et int est pas implicitement convertible en void.

J'attendre votre code à travailler sur la plupart des implémentations. Toutefois, sur au moins une mise en œuvre ( libc ++ ), il ne peut pas compiler:

test.cpp:7:30: error: no viable conversion from 'int (int)' to 'std::function<void (int)>'
    std::function<void(int)> ff = f;
                             ^    ~

Ironiquement, la raison de ce comportement découle de une autre question SO .

L'autre question a présenté un problème avec l'utilisation de std::function. La solution à ce problème implique la mise en œuvre ayant appliquer la requis: clause au moment de la compilation. En revanche, la solution à ce problème de question est interdisant la mise en œuvre de l'application de la requis. clause

Autres conseils

Votre cas d'utilisation est bien défini selon la norme.

Vous construire un std::function d'un objet appelable [1]

§20.8.11.2.1 / 7

template<class F> function(F f);

requis: F est CopyConstructible. f est appelable (20.8.11.2) pour les types d'arguments argTypes et le type de retour R.

Alors est votre f appelable?

§20.8.11.2 / 2 dit:

Un objet appelable f du type F est appelable pour les types d'arguments argTypes et le type de retour R si le expres- INVOKE (f, declval<ArgTypes>()..., R) sion, considéré comme un opérande non évalué (Article 5), est bien formée (20.8.2).

Et la définition de INVOKE dit:

§20.8.2

  1. Définir INVOKE (f, t1, t2, ..., tN) comme suit: ... des choses Dealing avec des pointeurs fonction / var membre ... -. f(t1, t2, ..., tN) dans tous les autres cas,

  2. Définir INVOKE (f, t1, t2, ..., tN, R) as INVOKE (f, t1, t2, ..., tN) converti implicitement à R.

Et depuis tout type peut être converti implicitement void, votre code devrait être très bien avec standarts conformes compilateur. Comme indiqué par litb ci-dessous, il n'y a pas une conversion implicite si vide ce n'est pas bien défini.

[1]: Je pense que les comptes lambda comme objet appelable, bien que je n'ai pas une référence pour cela. Votre lambda pourrait également être utilisé comme un pointeur de fonction car il capture pas de contexte

Cela ressemble peut être ok pour les fonctions anonymes.

Citation de http://www.alorelang.org/release/0.5/ doc / std_function.html (ce n'est pas de la bibliothèque standard C ++, mais on dirait qu'ils utilisent quelque chose de semblable là-dedans des liaisons vers le bas pour C ++)

objets de fonction ne peut être créé avec une définition de fonction, une expression de fonction anonyme ou en accédant à une méthode liée en utilisant l'opérateur point (.).

Une autre façon cela pourrait se faire est en stockant le pointeur de fonction automatique comme on le voit ici: http: / /en.wikipedia.org/wiki/Anonymous_function (C ++ section)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top