Le code suivant ne compile pas avec gcc ou clang.
template<class T>
class foo{};
template<class T>
class template_class_with_struct
{
void my_method() {
if(this->b.foo < 1);
};
struct bar
{
long foo;
} b;
};
Le message d'erreur est
error: type/value mismatch at argument 1 in template parameter list for 'template<class T> class foo'
8 | if(this->b.foo < 1);
L'erreur est causée par la classe templat foo. Lors de l'écriture de <= au lieu de <1, il se compile également.
Un indice apprécié?
Lien CompilerExplorer https://godbolt.org/z/v6Tygo
b.bar::foo
(this->b.foo) < 1
Réponses:
Dans GCC, je reçois
Ainsi, le compilateur pense que le
foo
sur cette ligne se réfère à la classefoo
ci-dessus et attend un argument de modèle. C'est similaire à ce que vous voyez.Lorsque vous le changez en
<=
, qui est symbolisé par le lexer comme un seul jeton. La prochaine étape ne voit même pas de<
, donc elle n'est pas confondue.Si vous changez la classe pour ne pas avoir le même nom que le long in
bar
, alors il n'a pas ce problème. Aussi, @ Jarod42 a des suggestions dans son commentaire à votre question (plus de qualification ou de parens).Les compilateurs sont écrits en étapes, où chaque étape traduit le code en une meilleure représentation pour la suivante, et chaque étape peut faire des choses de plus en plus complexes avec cette représentation.
Au début, le compilateur "lexe" le code, qui transforme les caractères individuels du fichier en un flux de jetons - il verrait cette ligne comme quelque chose comme
Et puis ça arrive au
foo
. Cela devrait probablement faireMais, il me semble que quand il voit
foo
, il regarde vers l'avant, voit le<
et le fait quifoo<class T>
existe et il essaie de faire un seul jeton,foo< ...
mais il ne peut pas trouver le>
pour le compléter.C'est juste une supposition - cela pourrait être une étape après le lexeur qui essaie de trouver des noms et peut combiner des jetons. Dans tous les cas, les multiples utilisations de foo le trompent.
la source