Question

Si je fais un pointeur à base de membres, je peux le convertir en un pointeur à membre dérivé généralement, mais pas quand il est utilisé dans un modèle comme Buzz ci-dessous, où les premières influences de l'argument de modèle le second . Suis-je lutte contre les bugs du compilateur ou ne le standard mandat vraiment ce travail pas?

struct Foo
{
    int x;
};

struct Bar : public Foo
{
};

template<class T, int T::* z>
struct Buzz
{
};

static int Bar::* const workaround = &Foo::x;

int main()
{
    // This works. Downcasting of pointer to members in general is fine.
    int Bar::* y = &Foo::x;

    // But this doesn't, at least in G++ 4.2 or Sun C++ 5.9. Why not?
    // Error: could not convert template argument '&Foo::x' to 'int Bar::*'
    Buzz<Bar, &Foo::x> test;

    // Sun C++ 5.9 accepts this but G++ doesn't because '&' can't appear in
    // a constant expression
    Buzz<Bar, static_cast<int Bar::*>(&Foo::x)> test;

    // Sun C++ 5.9 accepts this as well, but G++ complains "workaround cannot
    // appear in a constant expression"
    Buzz<Bar, workaround> test;

    return 0;
}
Était-ce utile?

La solution

Il est interdit simplement. Selon §14.3.2 / 5:

  

Les conversions suivantes sont effectuées sur chaque expression utilisé comme matrice argument de type non. Si un modèle argument non type ne peut pas être converti au type du paramètre de modèle-correspondant alors le programme est mal formé.
  - pour un modèle à paramètres non-type de type intégral ou de dénombrement, des promotions intégrales (4.5) et les conversions intégrales (4,7) sont appliqués
.   - pour un modèle à paramètres non-type de pointeur de type pour objet, les conversions de qualification (4.4) et le tableau de conversion à aiguille (4,2) sont appliqués.   - Pour un modèle paramètre non-type de référence de type à l'objet, aucune conversion applicables. Le type visé par la référence peut être plus cv-qualifié que le (autrement identique) le type de l'argument de la matrice. Le modèle paramètre est directement lié au modèle argument, qui doit être une lvalue.
  - Pour un modèle à paramètres non-type de pointeur de type de fonction, seule la fonction de conversion à aiguille (4,3) est appliqué. Si le modèle argument représente un ensemble de fonctions surchargées (ou un pointeur vers tel), la fonction d'appariement est choisi dans l'ensemble (13.4).
  - Pour un modèle paramètre non-type de référence de type à la fonction, aucune conversion applicables. Si le modèle argument représente un ensemble de fonctions surchargées, la fonction d'appariement est choisi dans l'ensemble (13.4).
  - Pour un modèle paramètre non-type de pointeur de type à fonction membre, aucune conversion applicables. Si le modèle argument représente un ensemble de fonctions membres surchargés, la fonction de membre de mise en correspondance est choisi dans l'ensemble (13.4).
  - Pour un modèle à paramètres non-type de pointeur de type à élément de données, les conversions de qualification (4,4) sont appliquées

.

Je l'ai souligné la conversion en ce qui concerne le pointeur aux membres de données. Notez que votre conversion (§4.11 / 2) ne figure pas. En C ++ 0x, il reste le même à cet égard.

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