IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Résultat inattendu : exemple tres simple d'imbrication de std::function


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de Ekinoks
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2003
    Messages
    687
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2003
    Messages : 687
    Par défaut Résultat inattendu : exemple tres simple d'imbrication de std::function
    Bonjour,

    J'ai eu aujourd'hui un résultat surprenant...
    Voici un exemple minimal qui reproduit le comportement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #include <iostream>
    #include <functional>
     
    struct test {
    	std::function<int()> fils;
     
    	test( std::function<int()> f ) : fils(f) {
    	}
     
    	test(  ) : fils([](){return 0;}) {
    	}
     
    	int operator() () {
    		return 1+fils();
    	}
    };
     
    int main(int argc, char const *argv[])
    {
    	std::cout << test(test(test()))() << std::endl;
     
    	return 0;
    }
    Le résultat affiché est 1....
    Pourquoi le résultat n'est pas 3 ???
    Le compilateur fait il une optimisation non légale ?

    Merci pour votre aide

    Edit : Je pensai avoir trouvé le bug.... mais en faite non... :^/

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Ca ne viendrait pas de la copie?

  3. #3
    Membre éclairé Avatar de Ekinoks
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2003
    Messages
    687
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2003
    Messages : 687
    Par défaut
    Citation Envoyé par ternel Voir le message
    Ca ne viendrait pas de la copie?
    Ho oui ! bien vue ! Il fait une copie plutôt que de convertir test en std::function.
    Merci =)

    Existe-t-il un moyen pour que la conversion soit prioritaire sur la copie ? Car si je rends la copie privée, alors je ne peux plus faire appelle a std::function<int()>( test() );

  4. #4
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    Mettre la copie privée, et ajouter un opérateur de conversion?
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  5. #5
    Membre éclairé Avatar de Ekinoks
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2003
    Messages
    687
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2003
    Messages : 687
    Par défaut
    Il y a un truc que je ne comprends pas dans le choix de la syntaxe du C++
    Pour quoi avoir choisi de spécifier une sémantique spéciale pour ClassA::ClassA(ClassA const & o) comme constructeur de recopie ??
    Ça enlève la possibilité de définir un constructeur classique qui prendrait en entrée un objet du même type que lui non ?

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    Un constructeur test( test t ) donnerai : pour créer une copie d'abord commencer par créer une copie que l'on reçoit en paramètre!!!! le constructeur de copie est forcément test( test const& ).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
       test()               // crée un objet temporaire de type test
       test()()             // appelle l'operator()() d'un temporaire de type test
       test::operator()     // désigne les operator() des objets de type test
       &test::operator()()  // est l'adresse de l'operator() qui ne reçoit pas de paramètre.
       test(test(test()))() // crée une copie de copie de copie d'un test et appelle son operator()()
    Rien dans cette dernière expression ne désigne test::operator() ou &test::operator()(), encore moins un std::function<int()> et donc a aucun moment on créera un test( std::function<int()> f ).
    Même en créant un operator std::function<int()>()const, l'expression continuera de désigner une copie de copie, car la non-conversion est toujours pré-envisagée avant une conversion.

    PS: rendre privé ou même détruire un constructeur ou une méthode n'empêchera jamais qu'il ne soit envisagé (si on tente de l'utiliser il y a erreur, mais jamais n'est envisagé un traitement substitutif à cause d'un protection.)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Encodage] test simple avec résultat inattendu
    Par paragoge dans le forum Langage
    Réponses: 4
    Dernier message: 16/05/2010, 11h52
  2. prob tres simple, form, method get
    Par killy-kun dans le forum Balisage (X)HTML et validation W3C
    Réponses: 8
    Dernier message: 25/08/2005, 10h29
  3. Réponses: 6
    Dernier message: 27/04/2005, 15h46
  4. [Defi] Query SQL qui semble tres simple
    Par Wakko2k dans le forum Langage SQL
    Réponses: 7
    Dernier message: 15/04/2004, 10h01
  5. Bon je vais essayer d'être simple :
    Par fpouget dans le forum Langage SQL
    Réponses: 8
    Dernier message: 09/04/2003, 17h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo