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 :

[gcc 4.7.2] bug avec template variadique


Sujet :

C++

  1. #1
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par défaut [gcc 4.7.2] bug avec template variadique
    Bonjour,

    Je pense être tombé sur un bug de gcc 4.7, mais avant de le rapporter j'aimerais savoir s'il a été résolu avec gcc 4.8 (que je n'arrive malheureusement pas à installer sur ma machine). Si quelqu'un passe par ici avec un gcc 4.8, ça serait sympa de me dire ce que ça donne chez vous :
    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 <type_traits>
     
    template<typename ... Args>
    struct make_return_t {
        static void make(const Args&... i) {}
    };
     
    template<typename ... Args>
    using make_return = make_return_t<typename std::decay<Args>::type...>;
     
    struct vec {
        template<typename ... Args>
        void operator () (const Args& ... i) {
            make_return<Args...>::make(i...);
        }
    };
     
    int main() {
    //    make_return<float, int>::make(0.0f,1);
     
        vec v;
        v(0.0f,1);
     
        return 0;
    }
    g++ -g -Wall -std=c++0x main.cpp -o main
    > g++ -v
    Using built-in specs.
    COLLECT_GCC=g++
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper
    Target: x86_64-linux-gnu
    Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.7.2-2ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
    Thread model: posix
    gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1)
    Voici l'erreur chez moi :
    main.cpp: In instantiation of ‘void vec::operator()(const Args& ...) [with Args = {float, int}]’:
    main.cpp:23:13: required from here
    main.cpp:10:70: error: wrong number of template arguments (2, should be 1)
    In file included from main.cpp:1:0:
    /usr/include/c++/4.7/type_traits:1677:11: error: provided for ‘template<class _Tp> class std::decay’
    Dé-commenter la première ligne du main fait disparaître l'erreur, et le code compile dans les deux cas avec clang.

  2. #2
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Je n'ai pas GCC 4.8, par contre sur GCC snapshot (20 juin) c'est fixé.

  3. #3
    Membre actif
    Homme Profil pro
    Ingénieur
    Inscrit en
    Octobre 2006
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Transports

    Informations forums :
    Inscription : Octobre 2006
    Messages : 48
    Par défaut
    Bonjour,

    J'ai pu tester avec les version suivantes de gcc :
    - 4.7.2 : confirmé
    - 4.8.0 : non reproduit
    - 4.8.1 : non reproduit

    J'observe le même comportement (le code compile sans erreur) avec gcc 4.7.2 en retirant le commentaire à la première ligne du main.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 641
    Par défaut
    Salut,

    Ce n'est pas un bug, c'est normal...

    Un variadic template peut prendre 0 paramètres ou plus.

    Lorsque tu écris un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template <typename ... Args>
    struct make_return_t {
        /* ...*/
    };
    tu définis make_return_t comme pouvant accepter... 0 paramètre ou plus.

    Mais, pour pouvoir récupérer le premier argument de ton variadic template, il faut pouvoir récupérer.. 1 paramètre ou plus.

    Et donc, si tu peux faire passer une structure prohe de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    template <typename first,typename ... Args>
    struct make_return_t {
        /* ...*/
    };
    pour la première version, tu ne peux en aucun cas faire admettre au compilateur que la première version, spécialisée sans argument puisse passer pour la seconde: quel serait le type du premier argument passé si... il n'y a aucun argument à passer

    Il faut donc que le compilateur sache au minimum qu'il existe la possibilité d'avoir une version de ta structure prenant au 1 argument ou plus.

    Tu arriveras à ce résultat grâce à une simple déclaration anticipée

    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 <type_traits>
     
    /* pour que le compilateur sache qu'il doit s'attendre à trouver des instanciations
     * spécialisant un argument ou plus
     */
    template <typename T, typename ... Args>
    strut make_return_t;
     
    template<typename ... Args>
    struct make_return_t {
        static void make(const Args&... i) {}
    };
     
    template<typename ... Args>
    using make_return = make_return_t<typename std::decay<Args>::type...>;
     
    struct vec {
        template<typename ... Args>
        void operator () (const Args& ... i) {
            make_return<Args...>::make(i...);
        }
    };
     
    int main() {
    //    make_return<float, int>::make(0.0f,1);
     
        vec v;
        v(0.0f,1);
     
        return 0;
    }
    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

  5. #5
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    760
    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 : 760
    Par défaut
    4.7.3: passe
    4.8.1: passe

    @koala: les paramètres ne sont pas utilisés. De plus ton exemple ne peut pas fonctionner, 2 déclarations de make_return_t différentes .

    Pour résoudre le problème je ne connait pas d'autre moyen qu'une spécification de template.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    template<typename ... Args>
    struct make_return_t;
     
    template <typename T, typename ... Args>
    struct make_return_t<T, Args> {
      static void make(const T& i, const Args&... other) {}
    };
     
    template <>
    struct make_return_t<> {
      static void make() {}
    };

  6. #6
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par défaut
    Je ne pense pas que ce soit un problème de nombre de paramètres, à titre d'exemple le code suivant compile parfaitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <type_traits>
    #include <tuple>
     
    template<typename ... Args>
    struct test {
        using type = std::tuple<typename std::decay<Args>::type...>;
    };
     
    int main() {
        test<>::type t;
     
        return 0;
    }
    Si l'erreur disparaît avec gcc 4.8 (voir même 4.7.3), c'est manifestement un bug.

    Quoi qu'il en soit, merci à tous pour vos retours !

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 16/08/2010, 17h08
  2. Bug avec requete
    Par arsgunner dans le forum ASP
    Réponses: 8
    Dernier message: 14/06/2004, 16h25
  3. [C#] Bug (?) avec la propriété TransparencyKey de la Form
    Par FrigoAcide dans le forum Windows Forms
    Réponses: 5
    Dernier message: 21/05/2004, 14h14
  4. [linux][gcc] Comment travaille t-on avec plusieurs fichiers?
    Par kaygee dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 02/04/2004, 17h48
  5. [CR9] Bug avec les champs à valeur vide ?
    Par Djob dans le forum SAP Crystal Reports
    Réponses: 3
    Dernier message: 15/07/2003, 21h21

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