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

Langage C++ Discussion :

fonction : passer par référence des paramètres optionnels


Sujet :

Langage C++

  1. #1
    Membre confirmé

    Inscrit en
    Octobre 2003
    Messages
    211
    Détails du profil
    Informations forums :
    Inscription : Octobre 2003
    Messages : 211
    Par défaut fonction : passer par référence des paramètres optionnels
    Bonjour.

    J'ai écris une fonction qui vérifie qu'une date chaine de cracatères est valide et qui la décompose en jour, mois et année si ces trois paramètres lui sont fournies.
    Je sais qu'il existe des fonctions qui vérifient la validité d'une date. Le problème n'est pas là.
    Je ne trouve pas la syntaxe correcte pour passer par référence un argument optionnel en lui donnant une valeur par défaut.
    voici ce que j'ai essayé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool date_valide(const std::string date, int &jour = 0, int &mois = 0, int &annee = 0);
    Ça ne plaît pas du tout au compilateur.
    Comme ce sont des pointeurs (puisque passage par référence), j'ai essayé avec nullptr.
    Ça ne lui a pas plu non plus.

    Est-ce que ce que je veux faire est réalisable?
    Si oui, pourriez-vous m'expliquer la syntaxe?

    Merci d'avance,

    Olivier

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 200
    Billets dans le blog
    4
    Par défaut
    Cette syntaxe n'a aucun sens. Une référence doit toujours référencer quelque chose qui existe ailleurs. Le compiler ne va pas s'inventer une référence temporaire local pour remplacer dans un appel de fonction.
    Utilise des pointeurs à nullptr par défaut et tu remplis ceux qui sont fournis lors de l'appel.
    Et au passage tu changes le premier paramètre pour être une const& pour éviter une copie superflue.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre confirmé

    Inscrit en
    Octobre 2003
    Messages
    211
    Détails du profil
    Informations forums :
    Inscription : Octobre 2003
    Messages : 211
    Par défaut
    donc je fais un appel comme suit ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ...
    int *j{nullptr};
    int *m[nullptr};
    int *a{nullptr};
    ...
    if (date_valide("15/10/2026",j,m,a)) 
    ...
    J'avais compris qu'un string était automatiquement passé par référence. Visiblement, ce n'est pas le cas.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 200
    Billets dans le blog
    4
    Par défaut
    Au moins ça va compiler, on va supposer que les nullptr sont gérés dans la fonction et c'est correct.
    Mais tu passes 3 nullptr... t'es sûr de savoir ce que tu fais ou tu tapes des trucs au hasard ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 862
    Par défaut
    Tu peux aussi utiliser la surcharge ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    bool date_valide(const std::string date);
    bool date_valide(const std::string date, int &jour, int &mois, int &annee);

  6. #6
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 331
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 331
    Par défaut
    Si au lieu d'un paramètre sortant tu renvoyais un optional sur un objet date?

    (et une string_view au lieu d'une string, même par référence constante -- sauf si utilises des fonctions avec une API C au lieu de celles standard du C++ pour décoder la date)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 636
    Par défaut
    UPDATE : trois commentaires supplémentaires le temps que je mûrisse le mien. Pardon pour la redite, le cas échéant.

    Bonjour,

    Citation Envoyé par olivier] Voir le message
    Bonjour.
    Comme ce sont des pointeurs (puisque passage par référence), j'ai essayé avec nullptr.
    Non ! Les références ne sont pas des pointeurs. Il se peut que le compilateur y recoure quand même en interne, dans le code généré, s'il n'a pas la visibilité directe sur ce à quoi on se réfère, mais ce n'est pas une nécessité.

    Sais-tu ce qu'est une adresse mémoire et as-tu besoin que l'on revienne sur les notions de pointeur (nécessaires en C et en C++) d'abord, puis de référence (introduites avec C++) ensuite ?

    Je ne trouve pas la syntaxe correcte pour passer par référence un argument optionnel en lui donnant une valeur par défaut.
    voici ce que j'ai essayé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool date_valide(const std::string date, int &jour = 0, int &mois = 0, int &annee = 0);
    J'ai mis un temps à comprendre où tu voulais en venir mais il apparait que c'est en fait dû à une erreur de conception initiale : tu souhaites passer des arguments par référence, mais faire référence à des valeurs par défaut si ceux-ci n'existent pas, et pour cela, il faut les construire. Ce qui te ramène donc à utiliser des arguments « par réf ou par copie selon les cas ». Ce n'est effectivement pas possible en C++ (ni dans les autres langages à ma connaissance, sauf à travailler à plus haut niveau comme le font les langages de script).

    Effectivement, ça peut être légitime dans certains cas ET cela nécessite de savoir comment sont traités les arguments d'une fonction à la base.

    J'ajoute que dans le cas présent, il est parfaitement inutile de passer des int par référence si on ne souhaite pas modifier leurs valeurs (pour les retourner au programme appelant) parce que les informations à transmettre en interne seront au moins aussi volumineuses que les int eux-mêmes. Mais la question reste pertinente pour des objets plus complexes.

    Est-ce que ce que je veux faire est réalisable?
    Oui, mais justement : tu travailles « une couche en dessous » de ce qui est proposé par les langages de script. C'est donc à toi de choisir judicieusement la meilleure approche à suivre et de la construire si nécessaire. C'est ce qui fait à la fois la force et l'intérêt du C++ pour un programmeur, mais également ce qui le rend difficile.

    Si oui, pourriez-vous m'expliquer la syntaxe?
    Comme expliqué, un int à lui seul ne véhicule qu'une valeur entière dans ℤ et aucune autre information. Donc :

    • Soit tu vas au plus simple et tu réserves des valeurs interdites à ces fins si c'est possible : par exemple, si tu sais que « -1 » ne sera jamais une valeur valide, tu peux l'utiliser comme marqueur pour indiquer une valeur inexistante. Si tu veux faire un peu plus propre, tu utilises une macro #define NO_VALUE -1. C'est ce qui ce fait en C, par exemple, ou en C++ avant constexpr. Ce n'est pas propre, mais c'est un moindre mal et ça évite de complexifier les types mis en œuvre et le code sous-jacent (tu ne manipules que des int qui, à leur tour, pourront toujours directement prendre place dans les registres du processeur) ;
    • Soit tu utilises la surcharge (comme indiqué par foetus entretemps). Le seul inconvénient (ou pas) est qu'il te faut surcharger autant de fois qu'il y a de configurations possibles (un, deux ou trois paramètres).
    • Soit tu définis un type qui soit compatible avec int et qui embarque toutes les informations nécessaires, c'est-à-dire la valeur numérique ET un flag indiquant si cette valeur est réellement passé ou si elle est inexistante, et en utilisant un pointeur privé en interne pour éviter d'avoir à faire la copie si on peut s'en passer. Et si tu utilises une version récente de C++, tu peux aussi vérifier si ce type n'a pas déjà été défini dans la bibliothèque standard à cette fin. On s'aperçoit alors que c'est exactement à cela que sert std::optional, donc on a parlé dans une de tes précédentes discussions.


    Mais plus généralement, ton problème récurrent, au lu de tes dernières discussions, est de pouvoir passer null à un argument, quel qu'il soit, quand c'est nécessaire et tel que cela se fait en Javascript, en SQL ou en Python. C'est sur cela qu'il faut plancher et il faudra au moins un commentaire entier pour expliquer pourquoi ce n'est pas directement possible à la base.

    Par ailleurs, si NULL a été très rapidement introduit en langage C (précisément parce que le besoin s'en est fait sentir), à la base, ce n'est même pas un mot-clé réservé du langage. C'est une macro définie officiellement par stddef.h, header lui-même défini par la norme et qui pose d'emblée les définitions standard. La plupart des gens en ignorent l'existence parce qu'en réalité, il est inclus (directement ou non) par tous les autres fichiers headers ou presque et on bénéficie de ses bienfaits dès ses premières lignes de code lorsque l'on apprend le langage. En général, il contient quelque chose comme :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    #define NULL ((void*)0)

    … et d'une manière générale, il est là pour définir un pointeur nul, donc pointant 0x00000000 sur toutes les architectures, ou ce qui s'en rapproche le plus quand ce n'est pas possible.

    Par contre, j'ai l'impression que tu as estimé, parce que tu en avais besoin, que les pointeurs étaient en fait « tout type du langage, augmenté de NULL » et ça, c'est précisément ce que les pointeurs ne sont pas.

Discussions similaires

  1. Réponses: 3
    Dernier message: 01/03/2016, 09h18
  2. Tout ce qui selon vous doit passer par des fonctions
    Par Mat_DZ dans le forum Langages de programmation
    Réponses: 22
    Dernier message: 13/11/2006, 11h50
  3. Réponses: 5
    Dernier message: 08/09/2006, 12h12
  4. Réponses: 2
    Dernier message: 19/04/2006, 13h43
  5. Réponses: 10
    Dernier message: 24/02/2004, 12h28

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