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

Boost C++ Discussion :

[Spirit] Un objet inexistant ?


Sujet :

Boost C++

  1. #1
    Invité2
    Invité(e)
    Par défaut [Spirit] Un objet inexistant ?
    Bonjour,

    On va faire court :

    Je tente d'appelé une fonction pour tout les caracète spéciaux que mon parseur va rencontrer et :

    Problèmes :
    obj\Debug\main.o||In function `ZN5boost6spirit4impl12radix_traitsILi16EE5digitIccEEbT_RT0_'
    )]+0x1f)||undefined reference to `void afficheur::operator()<char const*>(char const*, char const*) const'|
    )]+0x17)||undefined reference to `void unexpected_char::operator()<char>(char) const'|
    ||=== Build finished: 2 errors, 0 warnings ===|

    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
     
    // libs/cpp.h :
    #ifndef CPP_H_INCLUDED
    #define CPP_H_INCLUDED
    /*
        Nom du fichier :
            cpp.h
     
        Description du fichier :
            Fichier des prototypes du parseur du langage C++
     
        Nom du programme :
            KolorEngine
     
        Description du programme :
            KolorEngine est un programme réalisé en C++ qui parse plusieurs centaines de langages
     
        Date de debut :
            02/09/2008 - 12:05
     
        Date de fin :
            03/09/2008 - 12:15
     
        Version :
            0-09a
        Programmeur :
           Katagoto
     
    */
    #include <string>
    #include "..\tete.h"
    #include "..\afficheur.h"
     
    class CPP : public boost::spirit::grammar<CPP>{
        public:
     
        CPP();
     
        ~CPP(void);
     
        // Le parseur
        template <typename ScannerT>
        struct definition
        {
            definition(CPP const& self)
            {
                program
                    =  *boost::spirit::space_p >>
                        *(   preprocessor                   [self.preprocessor]
                        |   comment                         [self.comment]
                        |   keyword                         [self.keyword]
                        |   identifier                      [self.identifier]
                        |   special                         [self.special]
                        |   string                          [self.string]
                        |   literal                         [self.literal]
                        |   number                          [self.number]
                        |   boost::spirit::anychar_p        [self.unexpected]
                        |   type                            [self.type]
                        |   condition                       [self.condition]
                        |   boucle                          [self.boucle]
                        |   type                            [self.type]
                        |   objet                           [self.objet]
                        )
                    ;
     
                preprocessor
                    =   '#' >> *boost::spirit::space_p >> identifier
                    ;
     
                comment
                    =   +((boost::spirit::comment_p("//") | boost::spirit::comment_p("/*", "*/"))
                        >> *boost::spirit::space_p)
                    ;
     
                keyword
                    =   keywords >> (boost::spirit::eps_p - (boost::spirit::alnum_p | '_')) >> *boost::spirit::space_p
                    ;   // make sure we recognize whole words only
     
                keywords
                    =   "and_eq", "and", "asm", "auto", "bitand", "bitor",
                        "catch", "compl", "default", "enum", "export", "false",
                        "inline", "mutable", "namespace", "not_eq", "not",
                        "or_eq", "or", "register", "reinterpret_cast", "return",
                        "sizeof", "template", "true", "try", "typedef", "typeid",
                        "typename", "union", "unsigned", "using", "volatile", "xor_eq", "xor"
                    ;
     
                condition
                    =   conditions >> (boost::spirit::eps_p - (boost::spirit::alnum_p | '_')) >> *boost::spirit::space_p
                    ;   // make sure we recognize whole words only
     
                conditions
                    =   "if", "else", "elseif", "case", "switch"
                    ;
     
                boucle
                    =   boucles >> (boost::spirit::eps_p - (boost::spirit::alnum_p | '_')) >> *boost::spirit::space_p
                    ;   // make sure we recognize whole words only
     
                boucles
                    =   "while", "for", "break", "continue", "goto", "do"
                    ;
     
                objet
                    =   objets >> (boost::spirit::eps_p - (boost::spirit::alnum_p | '_')) >> *boost::spirit::space_p
                    ;   // make sure we recognize whole words only
     
                objets
                    =   "class", "struct", "private", "protected", "public", "throw", "this",
                        "new", "delete", "friend", "operator", "explicit"
                    ;
     
                type
                    =   types >> (boost::spirit::eps_p - (boost::spirit::alnum_p | '_')) >> *boost::spirit::space_p
                    ;   // make sure we recognize whole words only
     
                types
                    =   "bool", "int", "signed", "unsigned", "char", "double", "long", "short",
                        "static", "virtual", "void", "wchart", "float", "static_cast", "dynamic_cast",
                        "const_cast", "const", "extern"
                    ;
     
                special
                    =   +boost::spirit::chset_p("~!%^&*()+={[}]:;,<.>?/|\\-") >> *boost::spirit::space_p
                    ;
     
                string
                    =   !boost::spirit::as_lower_d['l'] >> boost::spirit::confix_p('"', *boost::spirit::c_escape_ch_p, '"')
                        >> *boost::spirit::space_p
                    ;
     
                literal
                    =   !boost::spirit::as_lower_d['l'] >> boost::spirit::confix_p('\'', *boost::spirit::c_escape_ch_p, '\'')
                        >> *boost::spirit::space_p
                    ;
     
                number
                    =   (   boost::spirit::real_p
                        |   boost::spirit::as_lower_d["0x"] >> boost::spirit::hex_p
                        |   '0' >> boost::spirit::oct_p
                        )
                        >>  *boost::spirit::as_lower_d[boost::spirit::chset_p("ldfu")]
                        >>  *boost::spirit::space_p
                    ;
     
                identifier
                    =   ((boost::spirit::alpha_p | '_') >> *(boost::spirit::alnum_p | '_'))
                        >> *boost::spirit::space_p
                    ;
            }
     
            boost::spirit::symbols<>
                keywords, types, conditions, boucles, objets;
     
            boost::spirit::rule<ScannerT>
                program, preprocessor, comment, special, string, literal,
                number, identifier, keyword, type, condition, boucle, objet;
     
            boost::spirit::rule<ScannerT> const&
            start() const
            {
                return program;
            }
        };
     
        afficheur   preprocessor, comment, keyword, identifier,
                    special, string, literal, number, type, condition, boucle, objet;
     
        unexpected_char unexpected;
     
        private:
        std::string dernier;
     
    };
    #endif // CPP_H_INCLUDED
     
    // lib/cpp.cpp :
    /*
        Nom du fichier :
            libs/cpp.cpp
     
        Description du fichier :
            Fichier de définition du parseur du langage C++
     
        Nom du programme :
            KolorEngine
     
        Description du programme :
            KolorEngine est un programme réalisé en C++ qui parse plusieurs centaines de langages
     
        Date de debut :
            02/09/2008 - 12:05
     
        Date de fin :
            03/09/2008 - 12:15
     
        Version :
            0-09a
        Programmeur :
           Katagoto
     
    */
    #include <string>
    #include "..\tete.h"
    #include "..\afficheur.h"
    #include "cpp.h"
     
    CPP::CPP() : preprocessor("preprocesseur", dernier)
        , comment("commentaires", dernier)
        , keyword("keywords", dernier)
        , identifier("identifier", dernier)
        , special("special", dernier)
        , string("chaine", dernier)
        , literal("literal", dernier)
        , number("number", dernier)
        , type("type", dernier)
        , condition("condition", dernier)
        , boucle("boucle", dernier)
        , objet("objet", dernier)
    {
    }
     
    CPP::~CPP(void)
    {
     
    }
     
    // tete.h :
    #ifndef TETE_H_INCLUDED
    #define TETE_H_INCLUDED
    /*
        Nom du fichier :
            tete.h
     
        Description du fichier :
            Fichier d'inclusion des headers vitaux aux parseurs
     
        Nom du programme :
            KolorEngine
     
        Description du programme :
            KolorEngine est un programme réalisé en C++ qui parse plusieurs centaines de langages
     
        Date de debut :
            04/10/2008 - 11:40
     
        Date de fin :
            04/10/2008 - 11:45
     
        Version :
            0-09a
        Programmeur :
           Katagoto
     
    */
    #include <boost/spirit.hpp>
    #include <boost/spirit/core.hpp>
    #include <boost/spirit/symbols/symbols.hpp>
    #include <boost/spirit/utility/chset.hpp>
    #include <boost/spirit/utility/escape_char.hpp>
    #include <boost/spirit/utility/confix.hpp>
     
    #endif // TETE_H_INCLUDED
     
    // afficheur.h :
    #ifndef AFFICHEUR_H_INCLUDED
    #define AFFICHEUR_H_INCLUDED
     
    /*
        Nom du fichier :
            afficheur.h
     
        Description du fichier :
            Fichier de déclaration des classes vitales au parseur
     
        Nom du programme :
            KolorEngine
     
        Description du programme :
            KolorEngine est un programme réalisé en C++ qui parse plusieurs centaines de langages
     
        Date de debut :
            02/09/2008 - 12:05
     
        Date de fin :
            03/09/2008 - 12:15
     
        Version :
            0-09a
        Programmeur :
           Katagoto
     
    */
    #include <string>
     
    template <typename CharT>
    void print_char(CharT ch);
     
    struct afficheur
    {
        afficheur(std::string name, std::string& dernier);
     
        template <typename IteratorT>
        void operator()(IteratorT first, IteratorT last) const;
     
        std::string name;
        std::string dernier;
    };
     
    struct unexpected_char
    {
     
        template <typename CharT>
        void operator()(CharT) const;
    };
     
    #endif // AFFICHEUR_H_INCLUDED
     
    // afficheur.cpp :
    /*
        Nom du fichier :
            afficheur.cpp
     
        Description du fichier :
            Fichier de définition des classes vitales au parseur
     
        Nom du programme :
            KolorEngine
     
        Description du programme :
            KolorEngine est un programme réalisé en C++ qui parse plusieurs centaines de langages
     
        Date de debut :
            02/09/2008 - 12:05
     
        Date de fin :
            03/09/2008 - 12:15
     
        Version :
            0-09a
        Programmeur :
           Katagoto
     
    */
    #include <string>
    #include <iostream>
    #include "afficheur.h"
     
    template <typename CharT>
    void print_char(CharT ch)
    {
        switch (ch)
        {
            case '<': std::cout << "&lt;";    break;
            case '>': std::cout << "&gt;";    break;
            case '&': std::cout << "&amp;";   break;
            case '"': std::cout << "&quot;";  break;
            default:  std::cout << ch;        break;
        }
    }
     
    afficheur::afficheur(std::string name, std::string& dernier)
        : name(name){}
     
    template <typename IteratorT>
    void afficheur::operator()(IteratorT first, IteratorT last) const
    {
        if(name!=dernier)
        {
            std::cout << "</span>";
            std::cout << "<span class=" << name << ">";
        }
        while (first != last)
            print_char(*first++);
     
    }
     
     
     
    template <typename CharT>
    void unexpected_char::operator()(CharT) const
    {
        std::cout << '#';
    }
    Par avance merci de votre aide

  2. #2
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    N'oublie pas que tout ce qui est template n'est pas compatible avec la définition en 2 parties : déclaration dans un en-tête et implémentation dans une unité de compilation.

    Cf la FAQ : http://cpp.developpez.com/faq/cpp/?p...VERS_templates

  3. #3
    Invité2
    Invité(e)
    Par défaut
    Citation Envoyé par Alp Voir le message
    N'oublie pas que tout ce qui est template n'est pas compatible avec la définition en 2 parties : déclaration dans un en-tête et implémentation dans une unité de compilation.

    Cf la FAQ : http://cpp.developpez.com/faq/cpp/?p...VERS_templates
    Je vais bosser ça, mais c'est bizzard que ça me dise rien pour les afficheurs, y a pourtant bien usage de template ?

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par katagoto Voir le message
    Je vais bosser ça, mais c'est bizzard que ça me dise rien pour les afficheurs, y a pourtant bien usage de template ?
    Il me semble que les deux erreurs que tu fournis concernent les afficheurs ou j'ai mal lu?

  5. #5
    Invité2
    Invité(e)
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Il me semble que les deux erreurs que tu fournis concernent les afficheurs ou j'ai mal lu?
    J'ai honte

  6. #6
    Invité2
    Invité(e)
    Par défaut
    ||=== MyParser, Debug ===|
    obj\Debug\main.o||In function `ZN9afficheurC2ESsRSs'
    \libs\..\afficheur.tpp|43|multiple definition of `afficheur::afficheur(std::string, std::string&)'|
    obj\Debug\libs\cpp.o:\_X\cpp\Exercices\KolorEngine\libs\..\afficheur.tpp|43|first defined here|
    obj\Debug\main.o||In function `ZN9afficheurC1ESsRSs'
    \Exercices\KolorEngine\libs\..\afficheur.tpp|43|multiple definition of `afficheur::afficheur(std::string, std::string&)'|
    obj\Debug\libs\cpp.o:\_X\cpp\Exercices\KolorEngine\libs\..\afficheur.tpp|43|first defined here|
    ||=== Build finished: 4 errors, 0 warnings ===|
    Pourtant j'ai tout fait comme il faut ? :

    // afficheur.h :
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    #ifndef AFFICHEUR_H_INCLUDED
    #define AFFICHEUR_H_INCLUDED
     
    /*
        Nom du fichier :
            afficheur.h
     
        Description du fichier :
            Fichier de déclaration des classes vitales au parseur
     
        Nom du programme :
            KolorEngine
     
        Description du programme :
            KolorEngine est un programme réalisé en C++ qui parse plusieurs centaines de langages
     
        Date de debut :
            02/09/2008 - 12:05
     
        Date de fin :
            03/09/2008 - 12:15
     
        Version :
            0-09a
        Programmeur :
           Katagoto
     
    */
    #include <string>
     
    template <typename CharT>
    void print_char(CharT ch);
     
    struct afficheur
    {
        afficheur(std::string name, std::string& dernier);
     
        template <typename IteratorT>
        void operator()(IteratorT first, IteratorT last) const;
     
        std::string name;
        std::string dernier;
    };
     
    struct unexpected_char
    {
     
        template <typename CharT>
        void operator()(CharT) const;
    };
     
    #include "afficheur.tpp"
    #endif // AFFICHEUR_H_INCLUDED
    // afficheur.tpp :
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
     
    /*
        Nom du fichier :
            afficheur.tpp
     
        Description du fichier :
            Fichier de définition des classes vitales au parseur
     
        Nom du programme :
            KolorEngine
     
        Description du programme :
            KolorEngine est un programme réalisé en C++ qui parse plusieurs centaines de langages
     
        Date de debut :
            02/09/2008 - 12:05
     
        Date de fin :
            03/09/2008 - 12:15
     
        Version :
            0-09a
        Programmeur :
           Katagoto
     
    */
    #include <string>
    #include <iostream>
     
    template <typename CharT>
    void print_char(CharT ch)
    {
        switch (ch)
        {
            case '<': std::cout << "&lt;";    break;
            case '>': std::cout << "&gt;";    break;
            case '&': std::cout << "&amp;";   break;
            case '"': std::cout << "&quot;";  break;
            default:  std::cout << ch;        break;
        }
    }
     
    afficheur::afficheur(std::string name, std::string& dernier)
        : name(name){}
     
    template <typename IteratorT>
    void afficheur::operator()(IteratorT first, IteratorT last) const
    {
        if(name!=dernier)
        {
            std::cout << "</span>";
            std::cout << "<span class=" << name << ">";
        }
        while (first != last)
            print_char(*first++);
     
    }
     
     
     
    template <typename CharT>
    void unexpected_char::operator()(CharT) const
    {
        std::cout << '#';
    }
    Quelqu'un aurait le courage de m'expliquer ?

    Par avance merci de votre aide
    Dernière modification par 3DArchi ; 15/10/2008 à 15h20. Motif: Séparation des deux bouts de code-> plus lisible

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour,
    CE qui est vrai pour les templates .... ne l'est pas pour les non template. Ton constructeur se trouve défini dans trois modules différents si j'en crois tes erreurs:
    dans main.cpp
    dans cpp.cpp
    et dans
    afficheur.tpp.

    Tu as deux solutions (qui sont la même):
    soit inclure l'implémentation du constructeur dans la définition de la classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct afficheur
    {
        afficheur(std::string name, std::string& dernier) : name(name){}
    ...
    soit déclarer afficheur comme inline:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct afficheur
    {
        inline afficheur(std::string name, std::string& dernier);
    ...
    P.S.: tu n'as pas besoin de rajouter afficheur.tpp comme module à compiler. Tes templates et ta structures seront de facto définis dès lors que afficheur.h sera inclue 1 fois et que les éléments template seront utilisés.

  8. #8
    Invité2
    Invité(e)
    Par défaut
    Je deviens fou

    ||=== KolorEngine, Debug ===|
    obj\Debug\libs\cpp.o||In function `ZN3CPPC2Ev'
    D:\_X\cpp\Exercices\KolorEngine\libs\cpp.cpp|43|undefined reference to `afficheur::afficheur(std::string, std::string&)'|
    D:\_X\cpp\Exercices\KolorEngine\libs\cpp.cpp|43|undefined reference to `afficheur::afficheur(std::string, std::string&)'|
    D:\_X\cpp\Exercices\KolorEngine\libs\cpp.cpp|43|undefined reference to `afficheur::afficheur(std::string, std::string&)'|
    D:\_X\cpp\Exercices\KolorEngine\libs\cpp.cpp|43|undefined reference to `afficheur::afficheur(std::string, std::string&)'|
    D:\_X\cpp\Exercices\KolorEngine\libs\cpp.cpp|43|undefined reference to `afficheur::afficheur(std::string, std::string&)'|
    obj\Debug\libs\cpp.o:\_X\cpp\Exercices\KolorEngine\libs\cpp.cpp|43|more undefined references to `afficheur::afficheur(std::string, std::string&)' follow|
    obj\Debug\main.o||In function `ZN5boost6spirit4impl12radix_traitsILi16EE5digitIccEEbT_RT0_'
    )]+0x1f)||undefined reference to `void afficheur::operator()<char const*>(char const*, char const*) const'|
    )]+0x17)||undefined reference to `void unexpected_char::operator()<char>(char) const'|
    ||=== Build finished: 8 errors, 0 warnings ===|
    J'ai changé juste ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template <typename CharT>
    inline void unexpected_char::operator()(CharT) const
    {
        std::cout << '#';
    }
    inline afficheur::afficheur(std::string name, std::string& dernier)
        : name(name){}
    Et j'inclus bien ..\afficheur.h

    Quelqu'un sait pourquoi ?

    Par avance merci de votre aide

  9. #9
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour,
    Ceci compile chez moi sans problème de link:
    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
    #ifndef AFFICHEUR_H_INCLUDED
    #define AFFICHEUR_H_INCLUDED
     
    #include <string>
     
    template <typename CharT>
    void print_char(CharT ch);
     
    struct afficheur
    {
        inline afficheur(std::string name, std::string& dernier);
     
        template <typename IteratorT>
        void operator()(IteratorT first, IteratorT last) const;
     
        std::string name;
        std::string dernier;
    };
     
    struct unexpected_char
    {
     
        template <typename CharT>
        inline void operator()(CharT) const;
    };
     
    #include "afficheur.tpp"
    #endif // AFFICHEUR_H_INCLUDED
    et afficheur.tpp:
    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
    37
    38
    39
    #include <string>
    #include <iostream>
     
    template <typename CharT>
    void print_char(CharT ch)
    {
        switch (ch)
        {
            case '<': std::cout << "&lt;";    break;
            case '>': std::cout << "&gt;";    break;
            case '&': std::cout << "&amp;";   break;
            case '"': std::cout << "\"";  break;
            default:  std::cout << ch;        break;
        }
    }
     
    inline afficheur::afficheur(std::string name, std::string& dernier)
        : name(name){}
     
    template <typename IteratorT>
    void afficheur::operator()(IteratorT first, IteratorT last) const
    {
        if(name!=dernier)
        {
            std::cout << "</span>";
            std::cout << "<span class=" << name << ">";
        }
        while (first != last)
            print_char(*first++);
     
    }
     
     
     
    template <typename CharT>
    inline void unexpected_char::operator()(CharT) const
    {
        std::cout << '#';
    }

  10. #10
    Membre chevronné
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Par défaut
    Bonjour,

    J'ai du mal à voir à quoi ressemble ton code actuellement. Peux-tu montrer le contenu de afficheur.h et .cpp ?

    Quel(s) module(s) utilisent print_char ? Si seule la classe afficheur l'utilise, fais-en une fonction membre privée.

    Enfin, de façon plus générale, je trouve que la technique des fichiers .tpp embrouille les débutants plus qu'autre chose.
    Tu as juste à savoir que la définition des fonctions templates (membres ou non) doivent être situées dans le même fichier que leur déclaration. Autrement dit, tout ce qui est template va dans un « .h ».
    Quand tu comprendras ce qu'est une unité de compilation, tu sauras ce que tu feras, et seulement à ce moment là tu utiliseras la technique des fichiers .tpp si tu en auras envie (mais franchement, c'est juste une question de goût, et personnellement je trouve cela totalement inutile).


    EDIT: 3DArchi > Plutôt que de lui proposer d'utiliser des fonctions inline (sait-il au moins ce que cela implique ?), pourquoi ne pas lui faire écrire un .cpp où seraient définies les fonctions membres non-template de la classe afficheur ?
    De plus, un constructeur inline, c'est très généralement une mauvaise idée, même s'il est en apparence vide.


    EDIT2 : Autre chose, rien à voir : tu n'initialises pas ta variable dernier ?
    Enfin, passe plutôt tes variables name et dernier par références constances au constructeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    afficheur::afficheur(const std::string& name, const std::string& dernier):
        name(name),
        dernier(dernier)
    {
    }
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  11. #11
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Florian Goo Voir le message
    EDIT: 3DArchi > Plutôt que de lui proposer d'utiliser des fonctions inline (sait-il au moins ce que cela implique ?), pourquoi ne pas lui faire écrire un .cpp où seraient définies les fonctions membres non-template de la classe afficheur ?
    De plus, un constructeur inline, c'est très généralement une mauvaise idée, même s'il est en apparence vide.
    Tu as totalement raison. Je n'ai pas eu la présence d'esprit de proposer tout de suite cette solution J'étais resté dans son raisonnement .h/.tpp.

  12. #12
    Invité2
    Invité(e)
    Par défaut
    inline, d'après ce que je sais, ça "recopie" la définition de ta fonction là où tu l'utilise, pour les optimisations je crois, donc j'ai :

    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    // ..\afficheur.h
    #ifndef AFFICHEUR_H_INCLUDED
    #define AFFICHEUR_H_INCLUDED
     
    /*
        Nom du fichier :
            afficheur.h
     
        Description du fichier :
            Fichier de déclaration des classes vitales au parseur
     
        Nom du programme :
            KolorEngine
     
        Description du programme :
            KolorEngine est un programme réalisé en C++ qui parse plusieurs centaines de langages
     
        Date de debut :
            02/09/2008 - 12:05
     
        Date de fin :
            03/09/2008 - 12:15
     
        Version :
            0-09a
        Programmeur :
           Katagoto
     
    */
    #include <string>
     
    template <typename CharT>
    void print_char(CharT ch);
     
    struct afficheur
    {
        afficheur(std::string name, std::string& dernier);
     
        template <typename IteratorT>
        void operator()(IteratorT first, IteratorT last) const;
     
        std::string name;
        std::string dernier;
    };
     
    struct unexpected_char
    {
     
        template <typename CharT>
        void operator()(CharT) const;
    };
     
    #endif // AFFICHEUR_H_INCLUDED
     
    // ..\afficheur.cpp :
    /*
        Nom du fichier :
            afficheur.cpp
     
        Description du fichier :
            Fichier de définition des classes vitales au parseur
     
        Nom du programme :
            KolorEngine
     
        Description du programme :
            KolorEngine est un programme réalisé en C++ qui parse plusieurs centaines de langages
     
        Date de debut :
            02/09/2008 - 12:05
     
        Date de fin :
            03/09/2008 - 12:15
     
        Version :
            0-09a
        Programmeur :
           Katagoto
     
    */
    #include <string>
    #include <iostream>
    #include "afficheur.h"
     
    template <typename CharT>
    void print_char(CharT ch)
    {
        switch (ch)
        {
            case '<': std::cout << "&lt;";    break;
            case '>': std::cout << "&gt;";    break;
            case '&': std::cout << "&amp;";   break;
            case '"': std::cout << "&quot;";  break;
            default:  std::cout << ch;        break;
        }
    }
     
    inline afficheur::afficheur(std::string name, std::string& dernier)
        : name(name){}
     
    template <typename IteratorT>
    void afficheur::operator()(IteratorT first, IteratorT last) const
    {
        if(name!=dernier)
        {
            std::cout << "</span>";
            std::cout << "<span class=" << name << ">";
        }
        while (first != last)
            print_char(*first++);
     
    }
     
     
     
    template <typename CharT>
    inline void unexpected_char::operator()(CharT) const
    {
        std::cout << '#';
    }
     
    // lib\cpp.h :
    #ifndef CPP_H_INCLUDED
    #define CPP_H_INCLUDED
    /*
        Nom du fichier :
            cpp.h
     
        Description du fichier :
            Fichier des prototypes du parseur du langage C++
     
        Nom du programme :
            KolorEngine
     
        Description du programme :
            KolorEngine est un programme réalisé en C++ qui parse plusieurs centaines de langages
     
        Date de debut :
            02/09/2008 - 12:05
     
        Date de fin :
            03/09/2008 - 12:15
     
        Version :
            0-09a
        Programmeur :
           Katagoto
     
    */
    #include <string>
    #include "..\tete.h"
    #include "..\afficheur.h"
     
    class CPP : public boost::spirit::grammar<CPP>{
        public:
     
        CPP();
     
        ~CPP(void);
     
        // Le parseur
        template <typename ScannerT>
        struct definition
        {
            definition(CPP const& self)
            {
                program
                    =  *boost::spirit::space_p >>
                        *(   preprocessor                   [self.preprocessor]
                        |   comment                         [self.comment]
                        |   keyword                         [self.keyword]
                        |   identifier                      [self.identifier]
                        |   special                         [self.special]
                        |   string                          [self.string]
                        |   literal                         [self.literal]
                        |   number                          [self.number]
                        |   boost::spirit::anychar_p        [self.unexpected]
                        |   type                            [self.type]
                        |   condition                       [self.condition]
                        |   boucle                          [self.boucle]
                        |   type                            [self.type]
                        |   objet                           [self.objet]
                        )
                    ;
     
                preprocessor
                    =   '#' >> *boost::spirit::space_p >> identifier
                    ;
     
                comment
                    =   +((boost::spirit::comment_p("//") | boost::spirit::comment_p("/*", "*/"))
                        >> *boost::spirit::space_p)
                    ;
     
                keyword
                    =   keywords >> (boost::spirit::eps_p - (boost::spirit::alnum_p | '_')) >> *boost::spirit::space_p
                    ;   // make sure we recognize whole words only
     
                keywords
                    =   "and_eq", "and", "asm", "auto", "bitand", "bitor",
                        "catch", "compl", "default", "enum", "export", "false",
                        "inline", "mutable", "namespace", "not_eq", "not",
                        "or_eq", "or", "register", "reinterpret_cast", "return",
                        "sizeof", "template", "true", "try", "typedef", "typeid",
                        "typename", "union", "unsigned", "using", "volatile", "xor_eq", "xor"
                    ;
     
                condition
                    =   conditions >> (boost::spirit::eps_p - (boost::spirit::alnum_p | '_')) >> *boost::spirit::space_p
                    ;   // make sure we recognize whole words only
     
                conditions
                    =   "if", "else", "elseif", "case", "switch"
                    ;
     
                boucle
                    =   boucles >> (boost::spirit::eps_p - (boost::spirit::alnum_p | '_')) >> *boost::spirit::space_p
                    ;   // make sure we recognize whole words only
     
                boucles
                    =   "while", "for", "break", "continue", "goto", "do"
                    ;
     
                objet
                    =   objets >> (boost::spirit::eps_p - (boost::spirit::alnum_p | '_')) >> *boost::spirit::space_p
                    ;   // make sure we recognize whole words only
     
                objets
                    =   "class", "struct", "private", "protected", "public", "throw", "this",
                        "new", "delete", "friend", "operator", "explicit"
                    ;
     
                type
                    =   types >> (boost::spirit::eps_p - (boost::spirit::alnum_p | '_')) >> *boost::spirit::space_p
                    ;   // make sure we recognize whole words only
     
                types
                    =   "bool", "int", "signed", "unsigned", "char", "double", "long", "short",
                        "static", "virtual", "void", "wchart", "float", "static_cast", "dynamic_cast",
                        "const_cast", "const", "extern"
                    ;
     
                special
                    =   +boost::spirit::chset_p("~!%^&*()+={[}]:;,<.>?/|\\-") >> *boost::spirit::space_p
                    ;
     
                string
                    =   !boost::spirit::as_lower_d['l'] >> boost::spirit::confix_p('"', *boost::spirit::c_escape_ch_p, '"')
                        >> *boost::spirit::space_p
                    ;
     
                literal
                    =   !boost::spirit::as_lower_d['l'] >> boost::spirit::confix_p('\'', *boost::spirit::c_escape_ch_p, '\'')
                        >> *boost::spirit::space_p
                    ;
     
                number
                    =   (   boost::spirit::real_p
                        |   boost::spirit::as_lower_d["0x"] >> boost::spirit::hex_p
                        |   '0' >> boost::spirit::oct_p
                        )
                        >>  *boost::spirit::as_lower_d[boost::spirit::chset_p("ldfu")]
                        >>  *boost::spirit::space_p
                    ;
     
                identifier
                    =   ((boost::spirit::alpha_p | '_') >> *(boost::spirit::alnum_p | '_'))
                        >> *boost::spirit::space_p
                    ;
            }
     
            boost::spirit::symbols<>
                keywords, types, conditions, boucles, objets;
     
            boost::spirit::rule<ScannerT>
                program, preprocessor, comment, special, string, literal,
                number, identifier, keyword, type, condition, boucle, objet;
     
            boost::spirit::rule<ScannerT> const&
            start() const
            {
                return program;
            }
        };
     
        afficheur   preprocessor, comment, keyword, identifier,
                    special, string, literal, number, type, condition, boucle, objet;
     
        unexpected_char unexpected;
     
        private:
        std::string dernier;
     
    };
    #endif // CPP_H_INCLUDED
     
    // lib\cpp.cpp :
    /*
        Nom du fichier :
            libs/cpp.cpp
     
        Description du fichier :
            Fichier de définition du parseur du langage C++
     
        Nom du programme :
            KolorEngine
     
        Description du programme :
            KolorEngine est un programme réalisé en C++ qui parse plusieurs centaines de langages
     
        Date de debut :
            02/09/2008 - 12:05
     
        Date de fin :
            03/09/2008 - 12:15
     
        Version :
            0-09a
        Programmeur :
           Katagoto
     
    */
    #include <string>
    #include "..\tete.h"
    #include "..\afficheur.h"
    #include "cpp.h"
     
    CPP::CPP() : dernier("")
        , preprocessor("preprocesseur", dernier)
        , comment("commentaires", dernier)
        , keyword("keywords", dernier)
        , identifier("identifier", dernier)
        , special("special", dernier)
        , string("chaine", dernier)
        , literal("literal", dernier)
        , number("number", dernier)
        , type("type", dernier)
        , condition("condition", dernier)
        , boucle("boucle", dernier)
        , objet("objet", dernier)
    {
    }
     
    CPP::~CPP(void)
    {
     
    }
    Erreurs :
    D:\_X\cpp\Exercices\KolorEngine\libs\cpp.h||In constructor `CPP::CPP()'
    D:\_X\cpp\Exercices\KolorEngine\libs\cpp.h|170|warning: `CPP::dernier' will be initialized after|
    D:\_X\cpp\Exercices\KolorEngine\libs\cpp.h|164|warning: `afficheur CPP::preprocessor'|
    D:\_X\cpp\Exercices\KolorEngine\libs\cpp.cpp|44|warning: when initialized here|
    obj\Debug\libs\cpp.o||In function `ZN3CPPC2Ev'
    \libs\cpp.cpp|44|undefined reference to `afficheur::afficheur(std::string, std::string&)'|
    \libs\cpp.cpp|44|undefined reference to `afficheur::afficheur(std::string, std::string&)'|
    \libs\cpp.cpp|44|undefined reference to `afficheur::afficheur(std::string, std::string&)'|
    \KolorEngine\libs\cpp.cpp|44|undefined reference to `afficheur::afficheur(std::string, std::string&)'|
    \libs\cpp.cpp|44|undefined reference to `afficheur::afficheur(std::string, std::string&)'|
    obj\Debug\libs\cpp.o:\libs\cpp.cpp|44|more undefined references to `afficheur::afficheur(std::string, std::string&)' follow|
    obj\Debug\main.o||In function `ZN5boost6spirit4impl12radix_traitsILi16EE5digitIccEEbT_RT0_'
    )]+0x1f)||undefined reference to `void afficheur::operator()<char const*>(char const*, char const*) const'|
    )]+0x17)||undefined reference to `void unexpected_char::operator()<char>(char) const'|
    ||=== Build finished: 8 errors, 3 warnings ===|
    Donc je fais quoi ?

    Par avance merci de votre aide

  13. #13
    Membre chevronné
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Par défaut
    Enlève le inline.
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  14. #14
    Invité2
    Invité(e)
    Par défaut
    Euh, bah

    On tourne en rond :
    ||=== MyParser, Debug ===|
    obj\Debug\main.o||In function `ZN5boost6spirit4impl12radix_traitsILi16EE5digitIccEEbT_RT0_'
    )]+0x1f)||undefined reference to `void afficheur::operator()<char const*>(char const*, char const*) const'|
    )]+0x17)||undefined reference to `void unexpected_char::operator()<char>(char) const'|
    ||=== Build finished: 2 errors, 0 warnings ===|

  15. #15
    Membre chevronné
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Par défaut
    Non non, ne t'inquiète point, on tourne pas en rond !

    Comme je le disais :
    Tu as juste à savoir que la définition des fonctions templates (membres ou non) doivent être situées dans le même fichier que leur déclaration. Autrement dit, tout ce qui est template va dans un « .h ».
    La définition de operator() doit être dans le .h !
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  16. #16
    Invité2
    Invité(e)
    Par défaut
    Merci, ça "marche",

    bon j'ai juste ça mais :
    ||=== MyParser, Debug ===|
    \libs\cpp.h||In constructor `CPP::CPP()'
    \libs\cpp.h|170|warning: `CPP::dernier' will be initialized after|
    \libs\cpp.h|164|warning: `afficheur CPP::preprocessor'|
    \libs\cpp.cpp|44|warning: when initialized here|
    ||=== Build finished: 0 errors, 3 warnings ===|
    Par avance merci de votre ultime aide

  17. #17
    Membre chevronné
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Par défaut
    Il faut que tu initialises tes objets dans le même ordre que leur déclaration.

    C'est ce qui se passe effectivement. Les objets sont créés dans l'ordre dans lesquels ils sont déclarés dans la définition de la classe.
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  18. #18
    Invité2
    Invité(e)
    Par défaut

    C'était ça
    Merci beaucoup

Discussions similaires

  1. [Débutant] Controle d'objets inexistants
    Par Poteuf dans le forum VB.NET
    Réponses: 2
    Dernier message: 13/04/2012, 11h45
  2. [MySQL] Mysql Objet inexistant ?
    Par fazpedro dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 26/09/2011, 14h39
  3. ORA-04043: objet inexistant
    Par sondo dans le forum Débuter
    Réponses: 5
    Dernier message: 13/02/2008, 17h11
  4. [SQL LOADER] sqlldr renvoit "objet inexistant"
    Par poubourna dans le forum Oracle
    Réponses: 3
    Dernier message: 23/07/2007, 11h52
  5. ORA-08103: objet inexistant
    Par Débéa dans le forum Oracle
    Réponses: 3
    Dernier message: 13/01/2006, 17h22

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