Frage

Wenn ich eine Vorlagenbasisklasse mit einer Vorlagenmethode habe:

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;
    }
};

Zum Beispiel vereinfache ich die Methode: Es muss nur dann "existieren", wenn t == u

Wenn a diese Klasse ist:

class A : public S<int> {};

Dann habe ich was ich will:

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

kompiliert, aber

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

Kompiliert nicht: Fehler: Keine Übereinstimmungsfunktion für den Anruf in 'a :: f (double &)' Es ist das erwartete Verhalten.

Jetzt lass uns einen Erben von erben S<double> Auch :

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

Dann kompiliert der folgende Code nicht:

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]

Ich hatte erwartet, dass es keine Unklarheit gibt: f<int> existiert nur für S<int>

Im Compiler -Fehler können wir feststellen, dass T bekannt ist, wenn dieses Stück Code kompiliert wird, jedoch nicht u (u = u).

Irgendeine Erklärung oder "Problemumgehung"?

War es hilfreich?

Lösung

Versuche dies:

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

... oder alternativ die Funktion injizieren A, z.B

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

Andere Tipps

Sie haben Recht, es existiert nur in S, aber zweimal. Einmal für jeden Typ, int und doppelt. In Ihrem Fall müssen Sie also genau angeben, welche Funktion Sie anrufen möchten. Die Lösung von NIM funktioniert einfach so.

Andere haben gute Problemumgehungen gegeben, aber ich möchte diese andere Frage beantworten, die Sie hatten

Ich hatte erwartet, dass es keine Unklarheit gibt: f<int> existiert nur für S<int>.

Du sagtest a.f(i) Es muss also zuerst nach Namen suchen f in A. Es findet zwei fs. Im S<int> und S<double>. Bei der Suche nach der Namensschauzeit weiß es noch nicht, dass es später nur ausgewählt hätte S<int>::f als Gewinner weil S<double>::f würde von Sfinae weggeworfen werden. Die klare Trennung von Namensuche und Überlastungsauflösung und Argumentabzug von Vorlagen erlaubt eine solche Vermischung nicht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top