Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

G++ 4.02 problémes avec l'héritage

7 réponses
Avatar
David Alloza
Bonjour,
Deja voila ma version de compilateur:
----------------------------------------------------------
ppu-lv2-g++ (GCC) 4.0.2 (CELL 4.0.34, $Rev: 848 $)
Copyright (C) 2005 Free Software Foundation, Inc.
-----------------------------------------------------------

C'est un compilateur destiné a la Playstation 3, mais j'ai aussi eu le même
problème avec la version embarquée dans le dernier xcode sur Mac.

Voila le genre de trucs qui ne veulent pas passer:

template< class PipelineType >
class edAudioCluster : public edAudio3DSoundEmitter< PipelineType >, public
CProcessingCluster
{

public:
edAudioCluster()
{
DebugSetDescription( "Cluster" );
AddNewEntry( &_Buffer );
}
....
Le compilateur me raconte qu'il ne connais pas les fonctions
DebugSetDescription et AddNewEntry
alors que ces fonctions sont définies dans la classe de base template
edAudio3DSoundEmitter dont ma classe hérite.
Ce code passe sans problèmes sur Visual studio (version .NET 2003), ainsi
que sur d'autres compilateurs.


Pour le faire passer sur ma version du GCC, voila ce que j'ai du faire

template< class PipelineType >
class edAudioCluster : public edAudio3DSoundEmitter< PipelineType >, public
CProcessingCluster
{
typedef edAudio3DSoundEmitter< PipelineType > ModuleBase;

edAudioCluster()
{
ModuleBase::DebugSetDescription( "Cluster" );
ModuleBase::AddNewEntry( &_Buffer );
}
C'est quand même assez lourd, je ne me voit pas bricoler de la sorte dans un
projet d'une taille conséquente.
Quelqu'un aurait il une solution moins contraigante a me proposer ?
En vous remerçiant par avance.

7 réponses

Avatar
Michel Decima


Pour le faire passer sur ma version du GCC, voila ce que j'ai du faire

template< class PipelineType >
class edAudioCluster : public edAudio3DSoundEmitter< PipelineType >, public
CProcessingCluster
{
typedef edAudio3DSoundEmitter< PipelineType > ModuleBase;

edAudioCluster()
{
ModuleBase::DebugSetDescription( "Cluster" );
ModuleBase::AddNewEntry( &_Buffer );
}
C'est quand même assez lourd, je ne me voit pas bricoler de la sorte dans un
projet d'une taille conséquente.


Qu'est ce que tu trouve lourd : le typedef, l'utilisation du prefixe
ModuleBase::, ou les deux ?

Si c'est l'utilisation du prefixe, tu dois pouvoir faire qqch comme ceci:

template< class PipelineType >
class edAudioCluster
: public edAudio3DSoundEmitter< PipelineType >
, public CProcessingCluster
{
typedef edAudio3DSoundEmitter< PipelineType > ModuleBase;
using ModuleBase::DebugSetDescription;
using ModuleBase::AddNewEntry;

edAudioCluster()
{
DebugSetDescription( "Cluster" );
AddNewEntry( &_Buffer );
}
};

Avatar
David Alloza
Deja merci pour cette réponse.
Ce que je trouve lourd est de devoir modifier pas mal de code dans un projet
pour pouvoir compiler en g++ 4.02.
Nous avons des projets de taille conséquente (plusieurs dizaines de
developpeurs travaillant dessus depuis plusieurs années), et faire
l'ensemble des modifs pour faire compiler ce genre de choses va entrainer un
nombre important de modifications.

Sinon, pour la solution a base du using ModuleBase, c'est celle que j'ai
commencé a implémenter dans quelques fichiers sources.

En fait, je n'arrive pas a comprendre pourquoi le g++ n'arrive pas a
compiler ce code, je n'ai pas d'héritage virtuel, donc il ne devrait même
pas avoir besoin qu'on lui spécifie la classe de base pour savoir quelle
méthode utiliser.

J'ai l'impression qu'il sait deja tout... mais qu'il me le demande quand
même.
C'est un peu déroutant.


"Michel Decima" a écrit dans le message de
news: eedvg2$dmu$

Qu'est ce que tu trouve lourd : le typedef, l'utilisation du prefixe
ModuleBase::, ou les deux ?

Si c'est l'utilisation du prefixe, tu dois pouvoir faire qqch comme ceci:

template< class PipelineType >
class edAudioCluster
: public edAudio3DSoundEmitter< PipelineType >
, public CProcessingCluster
{
typedef edAudio3DSoundEmitter< PipelineType > ModuleBase;
using ModuleBase::DebugSetDescription;
using ModuleBase::AddNewEntry;

edAudioCluster()
{
DebugSetDescription( "Cluster" );
AddNewEntry( &_Buffer );
}
};



Avatar
Michel Decima
Deja merci pour cette réponse.
Ce que je trouve lourd est de devoir modifier pas mal de code dans un projet
pour pouvoir compiler en g++ 4.02.
Nous avons des projets de taille conséquente (plusieurs dizaines de
developpeurs travaillant dessus depuis plusieurs années), et faire
l'ensemble des modifs pour faire compiler ce genre de choses va entrainer un
nombre important de modifications.
Sinon, pour la solution a base du using ModuleBase, c'est celle que j'ai
commencé a implémenter dans quelques fichiers sources.


La solution que j'ai propose devrait alleger un peu le travail, puisque
tu n'a plus besoin de prefixer partout (si elle marche).

En fait, je n'arrive pas a comprendre pourquoi le g++ n'arrive pas a
compiler ce code, je n'ai pas d'héritage virtuel, donc il ne devrait même
pas avoir besoin qu'on lui spécifie la classe de base pour savoir quelle
méthode utiliser.


C'est une histoire de visibilite des fonctions heritees dans un contexte
de classe template. Je crois bien qu'ici g++ applique le standard d'une
maniere plus rigoureuse que les autres (mais un specialiste de la norme
pourra confirmer/infirmer cela, et surtout donner l'interet de ce choix).

Avatar
Falk Tannhäuser
David Alloza wrote:
template< class PipelineType >
class edAudioCluster : public edAudio3DSoundEmitter< PipelineType >, pu blic
CProcessingCluster
{
public:
edAudioCluster()
{
DebugSetDescription( "Cluster" );
AddNewEntry( &_Buffer );
}
....
Le compilateur me raconte qu'il ne connais pas les fonctions
DebugSetDescription et AddNewEntry
alors que ces fonctions sont définies dans la classe de base template
edAudio3DSoundEmitter dont ma classe hérite.


Le plus simple pour faire passer la compilation est d'écrire
this->DebugSetDescription( "Cluster" );
this->AddNewEntry( &_Buffer );
Sinon, d'après la Norme, GCC a raison de ne pas chercher les noms dans
une classe de base qui dépend d'un paramètre du template. Cette règ le
(recherche de noms en 2 phases) n'est souvent pas implémentée dans le s
compilateurs plus anciens.

Falk

Avatar
David Alloza
Le plus simple pour faire passer la compilation est d'écrire
this->DebugSetDescription( "Cluster" );
this->AddNewEntry( &_Buffer );
Sinon, d'après la Norme, GCC a raison de ne pas chercher les noms dans
une classe de base qui dépend d'un paramètre du template. Cette règle
(recherche de noms en 2 phases) n'est souvent pas implémentée dans les
compilateurs plus anciens.
Falk


Effectivement c'est le plus simple.

j'ai donc réalisé mon portage GCC en utilisant soit la méthode a base de
this-> ou avec le mot clés using selon les cas.

aprés une journée passés a modifier des dizaines de fichiers sources, je
commence a approcher du but :)

merci.

Avatar
Yoxoman
Falk Tannhäuser :

Sinon, d'après la Norme, GCC a raison de ne pas chercher les noms dans
une classe de base qui dépend d'un paramètre du template. Cette règ le
(recherche de noms en 2 phases) n'est souvent pas implémentée dans le s
compilateurs plus anciens.


Aurais-tu des explications ou des références à cette règle ?

Avatar
Jean-Marc Bourguet
Yoxoman writes:

Falk Tannhäuser :

Sinon, d'après la Norme, GCC a raison de ne pas chercher les noms dans
une classe de base qui dépend d'un paramètre du template. Cette règle
(recherche de noms en 2 phases) n'est souvent pas implémentée dans les
compilateurs plus anciens.


Aurais-tu des explications ou des références à cette règle ?


Références: 3.4 et 14.6 dans la norme. Quoi, ce n'est pas clair?

Quand on a un nom non qualifié (sans ::, comme AddNewEntry), il y a deux
cas. Soit il dépend d'un paramètre template (parce que par exemple il a un
argument qui est d'un type paramètre) et alors il est cherché dans le
contexte d'instantiation, soit il ne dépend pas, et alors il est cherché
uniquement dans le contexte de définition du template.

L'objectif est de permettre à celui qui écrit un template d'avoir une assez
bonne idée de ce que va trouver le compilateur et de ne pas dépendre des
types paramètres sans s'en rendre compte. Ça permet aussi de vérifier un
peu plus la validité de la définition du template lorsqu'on la voit, sans
attendre une instantiation (dans le même genre, c'est ce qui a rendu
template et typename nécessaire en relation avec les noms dépendants).

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org