2016-06-15 9 views
1

Vererbung und Template-Betreiber ÜberlastungVererbung und Template-Operator Überlastung

Ich verstehe nicht, warum der Bediener in A<int> den Bediener in base den Schatten stellt. Es hat schließlich eine andere Unterschrift.

#include <iostream> 

struct base { 
    template <typename U> 
    void operator()(U&& x) { std::cout << "base" << std::endl; } 
}; 

template <typename T> 
struct A: public base { }; 

template <> 
struct A<int>: public base { 
    void operator()() { std::cout << "A<int>" << std::endl; } // line 1 
}; 

int main() 
{ 
    A<double>()(1); 
    A<int>()(1); // line 2 
    A<int>()(); // line 3 
} 

Zeile 2 wird nicht kompiliert, wenn Zeile 1 vorhanden ist.

Zeile 3 wird nicht kompiliert, wenn Zeile 1 (offensichtlich) entfernt wird.

Wenn ich die Operatorvorlage von Base nach A kopiere, funktioniert alles.

erwartete ich die Ausgabe zu sein:

base 
base 
A<int> 
+1

Es heißt * Name Verbergen *. Siehe z.B. http://stackoverflow.com/questions/1628768/why-does-an-overridden-function-in-the-derived-class-hide-other-overloads-of-the –

+0

Sie können das Problem lösen, indem Sie 'using base einfügen :: operator(); 'in Ihrer Klasse A. Beachten Sie, dass die Barrierefreiheit davon abhängt, wo Sie Ihre Verwendungsdeklarationen einfügen und dass Sie die Barrierefreiheit in Bezug auf die der Eltern ändern können (z. B. geschützte Funktionen öffentlich machen) Sektion). – Aconcagua

+0

Und beachten Sie, dass Sie eine einzelne Funktion auf diese Weise nicht "einblenden" können - entweder alle Überladungen oder keine (Ausnahme: es gibt nur eine Funktion mit einem gegebenen Namen im Elternteil ...). – Aconcagua

Antwort

2

Die Erklärung des Betreibers in der abgeleiteten Klasse versteckt den Namen in der Basisklasse.
Um lösen das Problem, ist es eine Frage eines using declaration:

template <> 
struct A<int>: public base { 
    using base::operator(); 
    void operator()() { std::cout << "A<int>" << std::endl; } 
}; 

Und beide werden zusammenstellen.

+0

Danke, das funktioniert. Ist der Punkt der "using-Deklaration" obligatorisch, um Probleme mit Mehrfachvererbung zu verhindern? Würde es ein Problem geben, wenn der Standard angibt, dass, wenn keine 'using-Deklaration 'vorhanden ist, die Funktion aus der ersten aufgelisteten Elternklasse verwendet wird? – SU3

+0

Beantwortet in einem Kommentar zu der Frage: http://Stackoverflow.com/a/1629074/2640636 Danke @Alan Stokes – SU3