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 :

erreur de compilation : no matching function for call to from_chars


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé

    Inscrit en
    Octobre 2003
    Messages
    211
    Détails du profil
    Informations forums :
    Inscription : Octobre 2003
    Messages : 211
    Par défaut erreur de compilation : no matching function for call to from_chars
    Bonjour.

    je sèche depuis un moment sur la compilation d'un bout de code.
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #include <algorithm>
    #include <cassert>
    #include <fstream>
    #include <charconv>
    #include <iostream>
    #include <string_view>
     
    #include <iomanip>
    #include <optional>
    #include <system_error>
     
    #include "Matrice.hpp"
     
    ...
     
    void Matrice::charger(std::string const &fichier_source)
    {
      std::ifstream lecture (fichier_source);
      std::string ligne {""};
      int valeur{};
     
      while (std::getline(lecture, ligne))
      {
        char sep {','};
        //std::string::iterator debut {std::begin(ligne)};
        //std::string::iterator fin {std::end(ligne)};
        //std::string::iterator pos_sep {};
        //auto debut {std::begin(ligne)};
        //auto fin {std::end(ligne)};
        auto debut {ligne.begin()};
        auto fin {ligne.end()};
        auto pos_sep {debut};
     
        pos_sep=find_if(debut,fin,sep);
        std::from_chars(debut, pos_sep-1 , m_nb_lignes);
    ...
    J'ai "gratté" autant que j'ai pu cppreference.com mais je n'ai pas trouvé mon erreur.

    À la compilation, il bloque sur l'appel à from_chars.
    C:\Users\1.formation.fr69\Documents\codeblocks\exoZestDeSavoir\Matrice\src\Matrice.cpp|38|error: no matching function for call to
    'from_chars(__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >, int&)'|
    j'ai ajouté toutes les bibliothèques citées dans les exemple, j'ai essayé d'ajouter 10 en dernier argument pour la base (apparemment, c'est optionnel), même résultat.
    j'ai essayé plein de choses en vain...

    L'un d'entre vous saurait-il m'expliquer où je commets une erreur ?

    j'avis oublié. ci dessous, ma classe Matrice où sont définis m_nb_lignes et m_nb_colonnes.
    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
    #ifndef MATRICE_HPP_INCLUDED
    #define MATRICE_HPP_INCLUDED
     
    #include <vector>
     
    class Matrice
    {
    public:
      // constructeurs
      Matrice()=default;
      Matrice(int nb_lignes, int nb_colonnes);
     
      void charger(std::string const &fichier);
      void afficher ();
     
     
    private:
      int m_nb_lignes {1};
      int m_nb_colonnes {1};
      std::vector<int> m_valeurs {};
    };
     
    #endif // MATRICE_HPP_INCLUDED

  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
    Est-ce que tu compiles bien en c++17 ou supérieur ?
    Si oui, il galère sans doute avec les conversions des itérateurs vers char*, aide le avec &*debut, &*pos_sep
    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
    Bonjour Bousk.

    a priori, je suis en c++17.
    J'utilise codeblocks 25.03

    Ta solution fonctionne mais pourquoi faut-il en passer par là ?
    ma syntaxe était-elle juste ou non ?

  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
    Ton code ne compile pas, donc non ta syntaxe est pas bonne
    Les iterators sont pas des char* que la méthode attend
    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
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 643
    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 643
    Par défaut
    (Edit : crosspost avec Bousk du à un appel téléphonique)

    Bonjour,

    Citation Envoyé par olivier] Voir le message
    Ta solution fonctionne mais pourquoi faut-il en passer par là ?
    ma syntaxe était-elle juste ou non ?
    Parce que std::from_chars attend explicitement des pointeurs vers des chars ( const char* first, const char* last, … ) mais que string::begin() et string::end() renvoient des itérateurs, donc des objets à part entière et pas des pointeurs natifs.

    Alors certes, ils sont faits pour respecter la même sémantique, notamment au niveau de l'incrémentation ++ et du déréférencement * et donc, lorsque c'est possible, ils bénéficient de conversions implicites. On sait aussi qu'incrémenter successivement l'itérateur renvoyé par .begin() doit aboutir in fine à la même valeur et au même type que celui renvoyé par .end() pour qu'ils puissent être comparés entre eux et former ainsi la condition d'arrêt, comme on le ferait avec des pointeurs ordinaires.

    Mais si *iterateur émule un déréférencement à la position courante et nous renvoie le caractère à la position courante (donc un char), rien ne nous dit en revanche qu'il le fasse sur une chaîne qui soit contiguë en mémoire ni même chargée entièrement, donc rien ne nous dit qu'extraire d'emblée deux pointeurs de nos itérateurs nous garantira qu'ils respecteront le même comportement. On ne sait pas non plus si le caractère qui est renvoyé l'est depuis une chaîne en mémoire (éventuellement celle renvoyée par .c_str() ) ou si son adresse est celle d'une variable statique interne ou d'une xvalue.

  6. #6
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    782
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 782
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Mais si *iterateur émule un déréférencement à la position courante et nous renvoie le caractère à la position courante (donc un char), rien ne nous dit en revanche qu'il le fasse sur une chaîne qui soit contiguë en mémoire ni même chargée entièrement, donc rien ne nous dit qu'extraire d'emblée deux pointeurs de nos itérateurs nous garantira qu'ils respecteront le même comportement. On ne sait pas non plus si le caractère qui est renvoyé l'est depuis une chaîne en mémoire (éventuellement celle renvoyée par .c_str() ) ou si son adresse est celle d'une variable statique interne ou d'une xvalue.
    Comme le montre son code, le container est un std::string, donc contiguë.

    Concernant cette partie du code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    pos_sep=find_if(debut,fin,sep);
    std::from_chars(debut, pos_sep-1 , m_nb_lignes);
    Le std::find_if n'est pas nécessaire et comme tu ne vérifie pas le résultat de from_chars, cela peut cacher des erreurs de format.

    Par exemple, avec la chaîne "123 456,789", le from_chars va trouver 123, alors que le pos_sep est après 456 qui sera ignoré. Le mieux est de prendre le retour de from_chars pour vérifier la présence du séparateur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    auto result = std::from_chars(&*debut, &*fin, m_nb_lignes);
    if (result.ec != std::errc()) { /* erreur */ }
    if (result.ptr == &*fin || *result.ptr != ',') { /* le séparateur est manquant */ }
    // continuer avec `result.ptr + 1`

  7. #7
    Membre confirmé

    Inscrit en
    Octobre 2003
    Messages
    211
    Détails du profil
    Informations forums :
    Inscription : Octobre 2003
    Messages : 211
    Par défaut
    Eh bé... avec mon niveau, je ne risquais pas de débrouiller ça tout seul!
    Merci de vos explications.

    Ce qui m'inquiète, c'est que, finalement, je n'ai pas compris grand'choses au C++. Pour moi, un itérateur était un pointeur. Je vais re-potasser le sujet.

    Mais du coup, comment fait-on pour utiliser from_char avec un string ?
    Autre question, std::begin(ligne) signifie-t-il la même chose que ligne.begin() ?

    jo_link_noir, l'utilisation find_if ne compilait pas.
    /usr/include/c++/14/bits/predefined_ops.h:318:30: error: expression cannot be used as a function
    Alors j'ai utilisé find.

    Et effectivement, je ne vérifie pas le résultat de from_char. Mais dans un premier temps je voulais déjà essayer de faire fonctionner avec des valeurs correctes.

    En fait, j'essaie de charger une matrice à partir d'un fichier.
    Je me doute bien que je réinvente probablement la roue, mais je voulais tester si j'y parvenais avec mes connaissance actuelles...
    Bon... je vous laisse évaluer la réponse

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

Discussions similaires

  1. Réponses: 16
    Dernier message: 22/04/2021, 11h26
  2. Réponses: 5
    Dernier message: 17/04/2016, 21h36
  3. Réponses: 7
    Dernier message: 14/03/2014, 22h50
  4. Réponses: 1
    Dernier message: 11/01/2014, 20h57
  5. no matching function for call
    Par pimousse280187 dans le forum Linux
    Réponses: 1
    Dernier message: 06/06/2009, 22h08

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