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 :

Spécialisation de classes et valeurs de retour


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut Spécialisation de classes et valeurs de retour
    Bonjour,

    j'ai un petit souci avec certaines fonctions membres d'une classe spécialisée. J'ai défini une classe Vector pour manipuler des vecteurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template<template<typename T>class storage,typename precision> Vector : storage<precision>
    {};
    Cette fonction admet pour paramètre une structure "storage" précisant le format de stockage de ses coefficients et une "precision" (int, float, double, ...). Pour le stockage, j'ai par exemple une structure dense :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template<typename precision> struct dense
    {
        size_t size_;
        precision* val_;
    };
    En fonction du format de stockage, je n'ai pas exactement les mêmes fonctions membres pour la classe Vector et je procède par spécialisation pour contourner ce problème. Dans le cas dense, j'ai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    template<typename precision> class Vector<dense,precision> : dense<precision>
    {
    public:
        Vector(Vector<dense,precision> const&);
    public:
        precision const sum() const;
        Vector<dense,precision> abs() const;
    };
    Dans cet exemple, le constructeur par copie et la fonction sum compilent bien mais pas la fonction abs. Le compilateur me jette en me disant qu'il a un problème avec la structure dense qui n'est pas conforme avec la façon dont est défini le paramètre storage dans la déclaration générale de Vector (la toute première). Seulement, je ne comprends pas pourquoi et je n'arrive pas à corriger le problème.

    Est-ce que quelqu'un aurait une idée?

    Merci pour votre aide.

  2. #2
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Tu aurais un code pour reproduire l'erreur ? Avec les informations actuelles ca compile très bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    template<class> struct dense;
     
    template<template<class> class, class>
    class Vector;
     
    template<class precision>
    class Vector<dense,precision> : dense<precision>
    {
      public:
        Vector<dense,precision> foo();
    };
    (Seul le point de vue syntaxe est vérifié par le compilo, il peut y avoir d'autre erreur lié à l'instanciation, mais il faut plus de code pour ca).

    NB: Tu peux marquer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Vector foo();
    //a la place de
    Vector<dense,precision> foo();

  3. #3
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut
    Merci pour ta réponse Flob90.
    Je viens de vérifier et apparemment Visual Studio 2010 refuse cette syntaxe. En revanche, avec la syntaxe que tu suggères en nota bene, ça compile nickel :
    Merci bien je passe en résolu!

  4. #4
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut
    Bonjour,

    désolé de revenir sur cette question mais j'ai finalement toujours le même problème, même s'il se pose un peu différemment. Voici le bout de code qui pose problème chez moi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    template<template<typename T> class stockage,typename precision> class Vecteur : stockage<precision> {};
     
    template<typename precision> class Vecteur<dense,precision> : dense<precision>
    {
    	Vecteur fun1(); // compile
    	Vecteur<dense,precision> fun2(); // ne compile pas
    	Vecteur<dense,int> fun3(); // ne compile pas
    };
     
    int main()
    {
    	Vecteur<dense,double> toto;
    	return 0;
    }
    Bien que fun2 ne compile pas, cela ne m'a finalement pas posé de problème puisque j'obtiens la compilation avec fun1, c'est-à-dire en ne précisant pas les paramètres template du Vecteur retourné (cf réponse de Flob90). J'en ai déduit que c'était juste un problème de syntaxe. Sauf que maintenant, j'ai besoin de déclarer une fonction fun3 qui renvoie un Vecteur<dense,int> et je me retrouve confronté au même problème que celui de départ, à savoir que ça ne compile pas.

    Qu'est-ce que je fais mal?

    Merci bien pour vos réponses!

    PS : je confirme que le code tel qu'il est donné ne compile pas. Si ça compile chez vous, c'est qu'il y a un problème avec mon compilo (Visual 2010).

    EDIT : erreur obtenue sous Visual 2010 : error C3200: 'dense<precision>'*: argument template non valide pour le paramètre de modèle 'stockage', modèle de classe attendu

    et voici le lien vers l'erreur : http://msdn.microsoft.com/en-us/library/3xwxftta.aspx qui affirme que je n'ai pas le droit de faire ce que je fais mais je me demande si c'est du made-in-microsoft ou si je ne respecte vraiment pas le langage. Dans le dernier cas, existe-t-il une solution de contournement autre que spécialiser ma classe pour toutes les précisions (horrible!)?

  5. #5
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut
    Je viens de trouver la solution : il faut supprimer les extensions de langage qui sont mises par défaut dans Visual (option /Za). Ca compile maintenant.

  6. #6
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Citation Envoyé par Aleph69 Voir le message
    Je viens de trouver la solution : il faut supprimer les extensions de langage qui sont mises par défaut dans Visual (option /Za). Ca compile maintenant.


    Si t'utilises VS2010 n'utilise pas /Za l'option est bugguée. :

    http://lists.boost.org/Archives/boos.../04/165531.php

    (et le bug est vraiment méchant)

  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
    Salut,
    Ca sent bon la régression. Le cas proposé dans le MSDN est différent : c'est comme si tu avais mis int à la place de dense.
    Désactiver les extensions de langage : je me souviens d'un vieux conseil d'Arzar m'ayant indiqué que cela était pas recommandé par MS, l'option de compil pouvant même devenir deprecated : cf ici

    Bon, j'arrive pas à mieux que ça :
    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
    #include <iostream>
     
    template<template<typename T> class stockage,typename precision> class Vecteur : stockage<precision> {};
     
    template<class T> struct dense{};
     
    template<typename precision> class Vecteur<dense,precision>; // (1)
     
    template<typename precision> struct rebind_vecteur_dense
    {
        typedef Vecteur<dense,precision> type;
    };
     
    template<typename precision> class Vecteur<dense,precision> : dense<precision>
    {
        public:
    	Vecteur fun1()
    	{
    	    std::cout<<"1\n";
    	    return Vecteur();
    	}
       typedef typename rebind_vecteur_dense<precision>::type type1;
    	type1 fun2()
    	{
    	    std::cout<<"2\n";
    	    return type1();
    	}
       typedef typename rebind_vecteur_dense<int>::type type2;
    	type2* fun3()
    	{
           type2 t;
           t.fun1();
           t.fun2();
    	    std::cout<<"3\n";
    	    return 0;
    	}
     
     //  type2 fun4()
    	//{
     //      type2 t;
     //      t.fun1();
     //      t.fun2();
    	//    std::cout<<"3\n";
    	//    return 0;
    	//}
    };
     
    int main()
    {
    	Vecteur<dense,double> toto;
    	toto.fun1();
    	toto.fun2();
    	toto.fun3();
    	Vecteur<dense,int> toto2;
    	toto2.fun1();
    	toto2.fun2();
    	toto2.fun3();
    	return 0;
    }
    Si j'essaie un retour par valeur (fun4), alors le compilateur plante (belle boite d'anomalie ) :
    AppName: cl.exe AppVer: 16.0.30319.1 AppStamp:4ba1dc05
    ModName: c1xx.dll ModVer: 16.0.30319.1 ModStamp:4ba1dc95
    fDebug: 0 Offset: 00107763
    Ceci dit, cela demanderait de se replonger dans la norme pour le // (1) et voir ce que cela implique par rapport à la spécialisation partielle qui suit.

  8. #8
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut
    Merci pour ta réponse 3DArchi.
    Je vais essayer de me renseigner sur ce fameux bug du compilo ou de voir comment contourner le problème sans désactiver les extensions de langage.
    J'ai quand même besoin de faire du code portable donc pour l'instant je suis bloqué.
    Je n'ai pas accès à la norme donc je vais devoir faire sans.

Discussions similaires

  1. Valeur de retour d'une procédure stockée
    Par Rudyweb dans le forum MFC
    Réponses: 4
    Dernier message: 25/02/2005, 17h52
  2. fonction operator, valeur de retour
    Par butch dans le forum C++
    Réponses: 21
    Dernier message: 20/09/2004, 10h30
  3. [VB6] Valeur de retour pour une Form
    Par preverse dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 17/08/2004, 17h16
  4. Valeur de retour d'une procédure externe
    Par elekis dans le forum x86 32-bits / 64-bits
    Réponses: 4
    Dernier message: 16/04/2004, 16h45
  5. Pourquoi une seule valeur de retour pour les fonctions ?
    Par Bruno75 dans le forum Langages de programmation
    Réponses: 33
    Dernier message: 18/01/2004, 13h58

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