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 C2894 :


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier Avatar de IlGi256
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2020
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2020
    Messages : 6
    Par défaut Erreur C2894 :
    Bonjour,
    J'ai un problème dont je ne parviens pas à trouver la solution
    Je voudrai faire un test de trie VECTOR via PAIR, mais j'ai un message d'erreur qui s'affiche.
    Error c2894 : Templates can not be declared to have "C" linkage
    Je pense qu'il doit s'agir d'un problème de compilation avec le compileur c++, puisque le code fonctionne sur d'autres compilateurs.

    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
     
    #include <algorithm>
    #include <iostream>
    #include <vector>
    #include <utility>
     
    using namespace std;
     
    int main() {
        vector<pair<string, int>> VSI_Liste{
            { "abc", 650 },
            { "cba", 804 },
            { "xyz", 305 }
        };
     
        sort(VSI_Liste.begin(), VSI_Liste.end(), [] (const auto &pair1, const auto &pair2) {
            return pair1.second < pair2.second;
        });
     
        for (const auto &pair : VSI_Liste) {
            cout << pair.first << " = " << pair.second << endl;
        }
     
        return 0;
    }
    Pouvez-vous m'aider à modifier ce code afin qu'il fonctionne ?

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Ce code n'a pas d'erreur.
    Tu dois avoir un extern "C" quelque part où c'est interdit pour cause de templates.
    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
    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,

    Je pense que cela vient de using namespace std;. Ça n'est pas pour rien que depuis 1998 on ne doit pas l'utiliser. Cette expression permet de dire : je récupère les milliers de noms définis dans l'espace de nom std. Une des contrepartie est que ces milliers de mots ne doivent pas être utilisés dans le code pour de nouveaux objets sous peine de d'erreurs de compilation voire des erreurs à l'exécution.

    Exemple : std::pair est le nom d'un template, on ne peut pas l'utiliser comme nom d'une variable (utilisé ligne 20).

  4. #4
    Membre régulier Avatar de IlGi256
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2020
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2020
    Messages : 6
    Par défaut Reponse
    Je pense qu'il s'agit de Templates dans le compilateur.
    J'ai testé sans le
    using namespace std;
    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
     
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <utility>
     
    using std::cout;
    using std::endl;
    using std::vector;
    using std::pair;
    using std::sort;
    using std::string;
     
    int main() {
        vector<pair<string, int>> VSI_Liste{
            { "abc", 650 },
            { "cba", 804 },
            { "xyz", 305 }
        };
     
        sort(VSI_Liste.begin(), VSI_Liste.end(), [] (const auto &pair1, const auto &pair2) {
            return pair1.second < pair2.second;
        });
     
        for (const auto &pair : VSI_Liste) {
            cout << pair.first << " = " << pair.second << endl;
        }
     
        return 0;
    }
    Cette fois-ci le compiler me dit que l'erreur est sur la ligne 24.
    Error c2894 : (24) Templates can not be declared to have "C" linkage
    Par conséquent, je pense que l'erreur vient de la composition dans la fonction sort(). Le compiler n’accepte pas cette écriture.
    Donc, peut-être une histoire de templates?
    Existe-t-il une autre forme d'écriture pour faire un trie de vector pair ?

  5. #5
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 759
    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 759
    Par défaut
    Parce que tu ne sais pas ce qu'est 1 espace de noms ou "namespace" en anglais, et comment les utiliser
    (et au passage que :: est 1 opérateur dit opérateur de résolution de portée, lien wiki en anglais)

    D'ailleurs, il est censé résoudre les conflits de noms comme tu as actuellement entre 2 fonctions qui s'appelle sort (<- si je comprends bien ton problème )

    Toi tu cherches std::sort (<- lien cplusplus en anglais)

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 636
    Par défaut
    (d'ailleurs, j'ai écrit ==>toute une prose<== sur les raisons pour lesquelles il ne faut pas utiliser la directive using namespace ...)

    Mais, de fait, en utilisant la directive using namespace std; on ne peut pas à la fois utiliser le terme pair pour désigner une std::pair à la ligne 10 et une variable (dans une boucle délimitée par des intervalles), dans la même fonction, à la ligne 20 (sans compter l'utilisation de pair1 et pair2 à la ligne 16 pour désigner des paramètres d'expression lambda )

    En outre, ton code m'inspire une réflexion dont certains ne manqueront sans doute pas de signaler qu'elle est hors sujet.

    Je crois cependant qu'il est nécessaire de rappeler l'importance du bon choix des termes pour désigner les éléments que l'on manipule.

    Si je peux (éventuellement) comprendre le choix de créer un std::vector<std::pair<std::string, int>>, il faut se dire que, au niveau de la fonction principale (main), il n'y a plus de généricité qui tienne:

    Ton tableau est sensé représenter "un ensemble d'éléments" bien particuliers. Or, VSI_Liste, moi, je suis désolé, mais ca ne me dit absolument rien.

    De la même manière, si chaque élément de ce tableau est -- effectivement -- constitué d'une chaine de caractères et d'un entier, je crois qu'il aurait sans doute été judicieux d'utiliser une structure, ou, à tout le moins, d'utiliser un alias de type pour les std::pair<std::string, int> dont le nom aurait donné une indication supplémentaire quant à l'usage que l'on est sensé en avoir.

    Car il ne faut pas oublier que le terme pair est le terme le plus générique que l'on puisse trouver pour représenter le fait que deux informations "cohabitent tant bien que mal" pour fournir une notion plus complexe.

    Si déjà, nous pouvions savoir à quel usage est destinée cette paire d'éléments, le code deviendrait sans doute immédiatement plus compréhensible, et il serait donc beaucoup plus facile de proposer un terme alternatif pour cette fameuse ligne qui fout le bordel:for (const auto &pair : VSI_Liste)Mieux encore: étant donné la possibilité qui nous est donnée depuis C++17 d'écrire un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    /* je présume que ta pair représente un couple habituel de clé et de valeur
     * mais il se peut que je sois complètement à la ramasse en faisant cette présomption
     * si bien que d'autres noms pourraient être mieux adaptés
     */
    for(auto const & [key, value]: VSI_Liste){
        std::cout<<key << " = " <<value<< "\n";
    }
    nous pourrions clairement indiquer l'usage auquel est destinée chaque partie de la std::pair à laquelle on a accès.

    Comprenons nous bien: je n'ai aucun problème face à l'utilisation d'un std::vector<std::pair<std::string, int>>, pour autant que la généricité qui se dégage de cet usage soit justifiée.

    Si tu te dis que ton tableau va devoir servir à trente six choses différentes, mais qu'il représentera toujours un concept similaire, cela peut, effectivement, valoir la peine de le maintenir aussi générique.

    Mais, dés le moment où tu destines clairement ce genre de tableau à un usage particulier -- par exemple, pour maintenir les différentes options dans une configuration -- il devient particulièrement important "d'en dire plus" à celui qui lira ton code.

    Comme je l'ai dit plus haut, un simple alias de type proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    using KeyAndValue = std::pair<std::string const, int>;
    pourrait très bien faire l'affaire, si tant est que ta paire est, effectivement, sensée représenter une clé et une valeur (raison pour laquelle std::string devrait être constante )

    Mieux encore, un "simple" alias de type pourrait nous indiquer clairement l'usage auquel nous destinons les éléments contenus dans le tableau. Que penserais tu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    using OptionList = std::vector<KeyAndValue>;
    (si tant est que le tableau serve effectivement à représenter effectivement une liste d'option)

    Pour conclure, je tiens à rappeler que le tout premier objectif d'un code n'est pas d'être correctement interprété par le compilateur.

    Bien sur, il s'agit là d'un objectif qu'il faudra aussi atteindre tôt ou tard; cependant, ce n'est pas le compilateur qui devra se charger de modifier le code s'il est incorrect, mais bien, le pauvre développeur, qui posera les yeux dessus.

    Si bien que le premier interlocuteur auquel ton code doit s'adresser, c'est à ce pauvre développeur, dont tu dois partir du principe qu'il ignore tout de tes objectifs:
    • si le développeur comprend tes objectifs et que le code ne fait pas ce qu'il est sensé faire, il sera en mesure de le corriger.
    • si ton code fait ce qu'il est sensé faire, mais que le développeur ne comprend pas tes objectifs, il sera dans l'incapacité d'y apporter d'éventuelles améliorations
    • si ton code ne fait pas ce qu'il est sensé faire, et que le développeur ne comprend pas tes objectifs, tu vas lui faire perdre des heures à essayer d'imaginer ce que tu voulais faire, avec une très grosse probabilité qu'il se vautre complètement en imaginant ce que tu voulais faire

    Et le pire de tout dans cette histoire, c'est que le développeur dont je parle ici, c'est ... toi, dans trois mois, six mois ou un an, alors que tu auras eu tout le temps nécessaire pour oublier toutes les "bonnes raisons" qui te semblent "si évidentes" aujourd'hui d'écrire le code tel que tu l'as écrit
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

Discussions similaires

  1. erreur C2894
    Par abbd dans le forum Visual C++
    Réponses: 7
    Dernier message: 11/07/2007, 09h38
  2. Erreur fréquente avec ASP et IIS
    Par Community Management dans le forum ASP
    Réponses: 2
    Dernier message: 11/02/2004, 22h20
  3. Réponses: 2
    Dernier message: 27/05/2002, 19h46
  4. erreur IDL:omg.org/CORBA/MARSHAL:1.0
    Par Pinggui dans le forum CORBA
    Réponses: 3
    Dernier message: 13/05/2002, 15h05
  5. [Kylix] Erreur objet
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 22/03/2002, 09h41

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