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

Langage C++ Discussion :

friend & espaces de nommage


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut friend & espaces de nommage
    Hello,

    J'ai défini un opérateur binaire * comme suit (il ne fait pas grand chose pour l'instant, j'en suis conscient) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    template <class T1, template<class> class StorageT1,
              class T2, template<class> class StorageT2>
    Matrix<T1, StorageT1>
    operator*(const Matrix<T1, StorageT1>& matrix1, const Matrix<T2, StorageT2>& matrix2)
    {
    	Matrix<T1, StorageT1> outMatrix(matrix1.nbRows, matrix2.nbColumns);
     
    	return outMatrix;
    }
    Lorsque je crée 3 matrices (qui sont accessoirement exactement du même type), et que je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    matrice3 = matrice1* matrice2;
    J'obtiens l'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ambiguous overload foroperator*’

  2. #2
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Exemple compilable si possible. Je ne vois pas de probleme a priori et n'en ai pas avec:

    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
    template <typename T> struct Storage;
     
    template <typename T, template <typename> class S>
    struct Matrix {};
     
    template <class T1, template<class> class StorageT1,
              class T2, template<class> class StorageT2>
    Matrix<T1, StorageT1>
    operator*(const Matrix<T1, StorageT1>& matrix1, const Matrix<T2, StorageT2>& matrix2)
    {
        Matrix<T1, StorageT1> outMatrix;
     
        return outMatrix;
    }
     
    int main()
    {
        Matrix<int, Storage> m1, m2, m3;
        m3 = m1*m2;
        return 0;
    }

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Alors en fait, ça semble venir du fait que la classe Matrix est en fait définie dans un espace de nommage, que l'opérateur soit défini en dehors de tout espace de nommage, et que l'opérateur * soit défini comme friend dans la classe Matrix.

    Je précise que dans le bout de code que j'avais donné, j'avais, pour des raisons de lisibilité, enlevé les références à l'espace de nommage précédent le nom de la classe Matrix.

    Quand j'enlève la déclaration friend, ça compile, mais ça m'ennuie, car je n'ai plus accès aux données internes de la matrice.

    Apparemment, le compilateur ne fait pas le lien entre la déclaration hors de l'espace de nommage (celle que je vous ai présentée), et la déclaration friend. Il les voit comme deux surcharges différentes, et en déduit une ambiguïté. J'ai essayé, dans la déclaration friend, de rajouter l'opérateur de portée ::

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template <class T1, template<class> class StorageT1,
              class T2, template<class> class StorageT2>
    friend Matrix<T1, StorageT1>
    ::operator*(const Matrix<T1, StorageT1>& matrix1, const Matrix<T2, StorageT2>& matrix2);
    mais j'obtiens l'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ISO C++ forbids declaration of ‘operator*’ with no type
    EDIT : en fait, mon problème ressemble assez à celui-ci. J'essaye de mettre en œuvre la solution proposée, mais ce n'est pas évident...

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Par ailleurs, j'avais initialement mis mon opérateur à l'intérieur de l'espace de nommage concerné, et ça amrchait très bien.

    Mais il m'a été dit qu"il fallait mettre les opérateurs binaires hors de tout espace de nommage, d'où mes actuels problèmes. Qu'en pensez-vous ?

  5. #5
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Pour moi il faut mettre les operateurs libres dans le meme espace de nommage que les classes qu'ils manipulent. (Ce qu'il ne faut pas faire, c'est mettre des operateurs binaires comme membres de la classe, c'est peut-etre avec ca que tu confondais).

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par oodini Voir le message
    en fait, mon problème ressemble assez à celui-ci. J'essaye de mettre en œuvre la solution proposée, mais ce n'est pas évident...
    Bon, après avoir lutté pour faire la déclaration anticipée de mes templates compliqués, au final, il considère toujours qu'il y a un opérateur * défini dans l'espace de nommage à cause de la déclaration friend, malgré ce que j'ai ajouté (en rouge) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template <class T1, template<class> class StorageT1,
                   class T2, template<class> class StorageT2>
    friend Matrix<T1, StorageT1>
    (::operator*) (const Matrix<T1, StorageT1>& matrix1, const Matrix<T2, StorageT2>& matrix2);

  7. #7
    screetch
    Invité(e)
    Par défaut
    ou bien une predeclaration de ton operateur * dans le namespace correct.
    en effet, si lorsque tu mets ta declaration friend, le compilateur n'a pas encore vu ton operateur *, il va declarer l'operateur * dans le namespace courant.

    si en revanche un operateur * a été declaré avant, et dans un namespace accessible, il va utiliser cette declaration.

    le problème est donc que en ajoutant friend, tu as declaré un operator* au mauvais endroit.

    remarque subsidiaire, ton operateur * dans le namespace global n'est pas friend de la classe puisque le compilo a compris ca différemment.

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    En l'occurrence, à présent, je déclare au début de mon code (mais après la déclaration anticipée de Matrix, rendue nécessaire...), en dehors de tout espace de nom :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    template <class T1, template<class> class StorageT1,
              class T2, template<class> class StorageT2>
    monNamespace::Matrix<T1, StorageT1>
    operator * (const monNamespace::Matrix<T1, StorageT1>& matrix1, const monNamespace::Matrix<T2, StorageT2>& matrix2);
    Ça devrait donc être bon.

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

Discussions similaires

  1. [Flash8] Espace de nommage dans un webservice
    Par memess dans le forum Flash
    Réponses: 1
    Dernier message: 01/03/2007, 09h19
  2. [c++] Mettre un callback dans un espace de nommage ou une class
    Par Spartan03 dans le forum GTK+ avec C & C++
    Réponses: 1
    Dernier message: 20/01/2007, 16h12
  3. Réponses: 2
    Dernier message: 05/09/2006, 10h08
  4. L'espace de nommage
    Par Shakan972 dans le forum C++
    Réponses: 1
    Dernier message: 02/11/2005, 15h49
  5. Réponses: 3
    Dernier message: 10/01/2005, 12h21

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