Question

Si j'ai une classe de base de modèle avec une méthode de modèle:

template <typename T>
class S
{
public:

    template <typename U>
    void f(U p, typename enable_if<is_same<T, U> >::type*dummy = 0)
    {
        std::cout << p << std::endl;
    }
};

Pour l'exemple, je simplifie la méthode: il doit « existe » que si T == U

Si A est cette classe:

class A : public S<int> {};

Ensuite, je dois ce que je veux:

int i = 1;
A a;
a.f(i);

compiles, mais

double d = 2.0;
a.f(d);

ne compile pas: erreur: aucune fonction de mise en correspondance pour l'appel à « A :: f (double et) » Il est le comportement attendu.

Maintenant, nous allons A Hériter de S<double> aussi:

class A : public S<int>, public S<double> {};

Ensuite, le code suivant ne compile pas:

int i = 1;
A a;
a.f(i);
error: request for member ‘f’ is ambiguous

error: candidates are: template<class U> void S::f(U, typename
boost::enable_if<boost::is_same<T, U>, void>::type*) [with U = U, T =
double]

error:                 template<class U> void S::f(U, typename
boost::enable_if<boost::is_same<T, U>, void>::type*) [with U = U, T =
int]

Je prévu il n'y a pas d'ambiguïté: f<int> existe uniquement pour S<int>

Dans l'erreur du compilateur, nous pouvons remarquer que T est connu lorsque ce morceau de code est compilé, mais pas U (U = U).

Toute explication ou "contournement"?

Était-ce utile?

La solution

Essayez ceci:

a.S<int>::f(i);

... ou bien injecter la fonction dans A, par exemple.

class A : public S<int>, public S<double> 
{
public:
  using S<int>::f;
  using S<double>::f;
};

Autres conseils

Vous avez raison, il existe uniquement dans S, mais deux fois. Une fois pour chaque type, int et double. Donc, dans votre cas, vous devrez spécifier exactement quelle fonction vous voulez appeler. La solution de Nim fonctionne comme ça.

D'autres ont donné de bons solutions de contournement, mais je veux répondre à cette autre question que vous avez

Je prévu il n'y a pas d'ambiguïté:. f<int> existe seulement pour S<int>

Vous avez dit a.f(i) donc il faut d'abord chercher le nom f dans A. Il trouve deux fs. Dans S<int> et S<double>. À l'époque de nom, il ne sait pas encore qu'il pourrait plus tard avoir S<int>::f seulement choisi comme gagnant parce S<double>::f serait jeté par SFINAE. La séparation claire de la recherche de nom et de la résolution de surcharge et de la déduction des arguments de modèle ne permet pas un tel entremêlement.

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