2016-04-05 6 views
0

Ich habe 2 Funktionen innerhalb einer Klasse, eine ist die Standard-Spezialisierung des Operators + =, die eine Funktion irgendeiner Art erwartet, während die zweite Spezialisierung einen EventHandler erwartet, hier ist die Implementierung:Explizite Funktion Template-Spezialisierung wählt die falsche Spezialisierung

template<typename _Func> 
    timed_function<_Sig>& operator+=(_Func &&f) 
    { 
     // Create an unamed handler 
     auto handler = new EventHandler<_Sig>("unamed", std::forward<_Func>(f)); 

     // Push it 
     _fs.push_back(handler); 

     // Return a reference to the function 
     return handler->get(); 
    } 

Hier ist die spezielle Version:

template<> 
timed_function<_Sig>& operator+=<const EventHandler<_Sig>&>(const EventHandler<_Sig> &_Handler) 
{ 
    // Copy the handler and push it 
    _fs.push_back(new EventHandler<_Sig>(_Handler)); 

    // Return a reference to the function 
    return _fs.back()->get(); 
} 

Wo _fs nur ein Vektor von EventHandler<_Sig> Pointers ist. Und _Sig ist die Funktion Signatur (zB void(int))

Wenn der Bediener mit Hilfe von + = zum Beispiel arbeitet eine Lambda-Funktion ist es ganz gut und der Compiler wählt die richtige Spezialisierung:

window->OnKeyDown() += [](dx::Window *sender, dx::KeyDownArgs &args) 
{ 
    [...] 
}; 

OnKeyDown() gibt einen Verweis zu einer Instanz von Event<void(dx::Window*, dx::KeyDownArgs&)>

Wenn ich jedoch versuche, manuell einen EventHandler wie folgt hinzuzufügen, wählt er trotzdem die nicht spezialisierte Version der Funktion.

window->OnKeyDown() += EventHandler<void(dx::Window*, dx::KeyDownArgs&)>("Key Handler", 
         [](dx::Window *sender, dx::KeyDownArgs &args) 
         { 
          [...] 
         }); 

Vielen Dank!

+0

'dx :: EventHandler' ist das gleiche wie' EventHandler'? – SergeyA

+0

Ja, ich werde es entfernen, damit es leichter zu verstehen ist, danke. – PsychoBitch

Antwort

0

Um richtig spezialisiert haben, verwenden Sie einfach

template<> 
timed_function<_Sig>& operator+=<const EventHandler<_Sig>>... 

Das heißt, entfernen Sie den Verweis aus Template-Spezialisierung. Hier ist ein Beispiel dafür, wie diese Art von Spezialisierung arbeiten sollte - mit gekochtem-up-Typ, soll aber nützlich sein:

http://coliru.stacked-crooked.com/a/297df51929329484

(abhängig von Ihrem Compiler, könnten Sie ein Leerzeichen zwischen ‚setzen müssen >> "in Spezialisierung).

+0

Seltsamerweise verursacht dies den gleichen exakten Fehler, der ungefähr 140 Mal in derselben Zeile ausgelöst wird. Das Entfernen der Referenz aus der Spezialisierung verursacht den Compiler, also sagen wir, dass die Spezialisierung schlecht ist. @SergeyA – PsychoBitch

+0

@PsychoBitch, bitte geben Sie den vollständigen Code der Spezialisierung. Du hast definitiv ein Problem dort. – SergeyA

+0

Hier: http://pastebin.com/nxTRdbtn – PsychoBitch

1

Sie bieten EventHandler<_Sig>&& nicht ein const EventHandler<_Sig>&, so dass die nicht spezialisierte Version gewählt wird.

+0

Ich dachte, das könnte die Ursache sein, die Frage ist, wie würde man es lösen? Vielen Dank. – PsychoBitch

+0

@PsychoBitch, siehe meine Antwort. – SergeyA

+0

@PsychoBitch: Drehen Sie Ihre Vorlage zu 'Vorlage timed_function & Operator + = (const F & f)' könnte eine Lösung sein. SFINAE und überladen eine andere oder partielle Spezialisierung von (Helfer-) Struktur. Oder sei im Aufruf explizit, wie SergeyA andeutet. – Jarod42