2009-02-12 9 views
2

Je suis en train de compiler le code d'un projet open source, et je suis en cours d'exécution dans un problème où gcc prétend qu'une ligne de code a une interprétation ambiguë. Le problème implique une classe et ces deux templated méthodes:opérateur désambiguïser [] liant

template <class X> 
class A { 
public: 
    X& operator[] (int i) { ... } 
    operator const X*() { ... } 
}; 

Lorsque cela est utilisé dans le sens de celle-ci:

A<B*> a; 
B* b = a[i]; 

gcc se plaint de la résolution ambiguë d'un [i]. Le problème est rendu plus clair en remplaçant la définition de A avec son instanciation:

class A_B { 
public: 
    B*& operator[] (int i) { ... } 
    operator B* const *() { ... } 
}; 

Le problème est qu'il ya deux façons d'interpréter B * b = a [i]:

// First interpretation (array-like behaviour first) 
B*& b1 = a[i]; 
B* b2 = (B*) b1; 

// Second interpretation (casting behaviour first) 
B* const * b1 = (B* const *) a; 
B* b2 = b1[a]; 

ma question est la suivante: y at-il un moyen de fournir une interprétation préférée, de préférence en faisant la version de coulée indésirable sans transtypage explicite, de sorte que je n'ai pas de modifier chaque ligne qui tente d'invoquer un []? Je me rends compte que l'interprétation est légitimement ambiguë, mais je sais ce que l'intention du code, et je voudrais communiquer que le compilateur avec des changements minimes.

Modifier: Il semble que mon exemple ne provoque pas le bogue en question, donc je ne résume pas correctement le code d'origine, ni d'identifier correctement le problème. Je vais essayer d'obtenir un exemple qui produit le problème en premier, désolé les gens.

+0

Etes-vous sûr que quelque chose d'autre ne se passe pas? J'ai compilé votre exemple avec gcc -Wall et ça ne donne pas tellement de peep. –

+0

Il semble compilé très bien pour les gens qui ont écrit aussi. Quelle version de gcc utilisez-vous? J'ai rencontré ce problème en compilant avec gcc 4.0.1. – Tony

Répondre

2

Le code suivant se compile pour moi avec g ++ 3.x. Je ne pense pas que votre analyse du problème soit correcte, mais en tout cas, pourriez-vous poster le message d'erreur que vous obtenez.

template <class X> 
struct A { 
    X& operator[] (int i) { static X x; return x; } 
    operator const X*() { return 0; } 
}; 

class B {}; 

int main() { 
    A<B*> a; 
    B* b = a[0]; 
} 
2

Vous pouvez utiliser des accolades:

A<B*> a; 
B* b = (a[i]); // Now it must evaluate the sub-expression a[i] 

NB. Votre exemple ci-dessus compile bien et appelle l'opérateur [] comme prévu.

0

Vous pouvez forcer le compilateur à se lier à operator [ ] par ceci:

B* b = a::operator [ ] (0); 

Mais de toute façon, la définition des conversions est toujours une mauvaise idée. Je chercherais dans tous les sens avant de recourir à des opérateurs de conversion.