Question

Un ami et moi discutions de modèles C++.Il m'a demandé ce qu'il doit faire:

#include <iostream>

template <bool>
struct A {
    A(bool) { std::cout << "bool\n"; }
    A(void*) { std::cout << "void*\n"; }
};

int main() {
    A<true> *d = 0;
    const int b = 2;
    const int c = 1;
    new A< b > (c) > (d);
}

La dernière ligne principale dispose de deux raisonnable analyse.Est 'b' l'argument de modèle ou est b > (c) l'argument de modèle?

Bien que, il est trivial de le compiler, et voyons ce que nous obtenons, nous nous demandions ce qui résout l'ambiguïté?

Était-ce utile?

La solution

Autant que je sache, il serait compilé comme new A<b>(c) > d.C'est la seule façon raisonnable de l'analyser à mon humble avis.Si l'analyseur ne peut pas assumer en vertu des circonstances normales, une > à la fin d'un argument de modèle, le résultat serait beaucoup plus d'ambiguïté.Si vous voulez de l'autre façon, vous devriez avoir écrit:

new A<(b > c)>(d);

Autres conseils

Comme l'a déclaré Leon & Lee, 14.2/3 (C++ 03) définit explicitement ce comportement.

C++ 0x ajoute au plaisir avec une règle similaire s'appliquant à >>.Le concept de base, c'est que lors de l'analyse d'un modèle de la liste d'arguments non imbriquées >> seront traités comme deux distincts > > jetons et pas le décalage à droite de l'opérateur:

template <bool>
struct A {
  A(bool);
  A(void*);
};

template <typename T>
class C
{
public:
  C (int);
};

int main() {
    A<true> *d = 0;
    const int b = 2;
    const int c = 1;
    new C <A< b  >>  (c) > (d); // #1
    new C <A< b > >  (c) > (d); // #2
}

'#1 et#2 " sont l'équivalent dans le ci-dessus.

Bien sûr, cela résout que la gêne d'avoir à ajouter des espaces imbriqués spécialisations:

C<A<false>> c;  // Parse error in C++ '98, '03 due to "right shift operator"

Le standard C++ définit que si, pour un nom de modèle suivi par un <, le < est toujours le début de l'argument de modèle de liste et le premier non-imbriquées > est considéré comme la fin du modèle de la liste d'arguments.

Si vous avez prévu que le résultat de l' > exploitant l'argument de modèle, alors vous devrez mettre l'expression entre parenthèses.Vous n'avez pas besoin de parenthèses si l'argument a été le cadre d'un static_cast<> ou un autre modèle d'expression.

La gourmandise de l'analyseur lexical est probablement le facteur déterminant en l'absence de parenthèses pour le rendre explicite.Je suppose que l'analyseur lexical n'est pas gourmand.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top