2016-06-20 11 views
1

Ich habe eine Vector-Klasse (nicht die eine eingebaut). Ich möchte eine integrierte Funktion schreiben, mit der ich die Vector-Klasse durchlaufen kann. Der Vektor-Klasse wird auf diese Weise definiert:Funktor funktioniert nicht in C++

template <typename T> class Vector{int _size; int _capicity ; T* _elem; 
    /(protected and public functions/}; 

Dann habe ich eine öffentliche Funktion Traverse schreiben:

template <typename T> template <typename VST> 
void Vector<T>::traverse (VST& visit) 
{ for (int i = 0; i < _size; i++) visit (_elem[i]); } 
//visit here represent some action that I am gonna perform on the elements 

den Code zu testen: Ich schreibe einen Funktor _elem auszuführen [i] ++ auf alle Elemente der Vektorklasse.

template <typename T> 
struct Increase 
    {virtual void operator() (T& e) { e++; } }; 

Im Hauptprogramm, schreibe ich eine Funktion:

template <typename T> 
void increase (Vector<T> & V) 
{ V.traverse (Increase<T>()); } 

Hinweis: Diese Funktion unterscheidet sich von der Erhöhung Funktion, die ein Funktor ist.

Hier ist, wie ich mein Programm testen:

Vector<int> c={1,2,3,4,5}; //initialize my vector class 
increase(c); 

Es gibt Fehlermeldung:

no match function for call to 'traverse'. 

ich es herausfinden, etwas mit der Art und Weise zu tun haben könnte ich Traverse erklären.

void Vector<T>::traverse (VST& visit); 
V.traverse (Increase<T>());//this is the way I called this function. 

Dann entferne ich die „&“ hier und VST-Besuch nutzen und dieses Mal ist es funktioniert, aber ich habe immer noch ein großes Problem, dass ich weiß nicht, warum ich nicht VST & Besuch als Variable verwenden kann die Verfahrfunktion.

Es scheint mir in Ordnung, durch Verweis zu übergeben.

Antwort

0

Take VST durch Wert in der Traverse-Funktion. Derzeit übergeben Sie ein r-Wert-Objekt, das nur von const-reference (const T &) oder r-value reference (T & &) akzeptiert werden kann [das wird universelle Referenz mit Vorlage].

template <typename T> 
template <typename VST> 
void Vector<T>::traverse (VST visit) 
{ 
    for (int i = 0; i < _size; i++) visit (_elem[i]); 
} 

Um es durch Bezugnahme funktioniert, zuerst eine l-value Instanz des Funktors erstellen und dann traverse nennen.

template <typename T> 
void increase (Vector<T> & V) 
{ 
    Increase<T> inc; 
    V.traverse (inc); 
} 

Aber lieber es nach Wert übergeben, wenn Sie können. STL nimmt functor von Wert. Außerdem sollten Sie nicht von const-reference nehmen, wie gut, denn dann müssen Sie Ihre operator()const auch

+0

Vielen Dank! Nur um sicherzugehen, ist das, weil ich einen Funktor auf diese Weise nicht passieren sollte? Weil ich in meiner Funktion ein r-Wert-Objekt an eine l-Wert-Referenz übertrage. – youyou

+0

Entschuldigung, ich habe dich nicht verstanden. Das Problem, das Sie gesehen haben, war, weil Sie einen temporären (r-Wert) an eine Funktion übergeben haben, die nur die l-Wert-Referenz akzeptiert. Diese Bindung funktioniert nicht. Provisorien können nur gebunden werden, indem sie entweder nach Wert oder nach Konst-Referenz oder nach R-Wert-Referenz genommen werden (nur in C++ 11) – Arunmu

+0

Vielen Dank, jetzt verstehe ich, was das Problem in meinem Code ist. Ich sollte nicht versuchen, eine temporäre (Increase ()) zu einer l-Wert-Referenz zu übergeben. – youyou

0

Ihr Problem machen ist, dass Sie einen temporären passieren versuchen, Increase<T>(), als nicht konstanten Referenz-Parameter. C++ erlaubt nur Provisorien, an konstante Referenzparameter (oder R-Wert-Referenzparameter) zu binden.

Die Lösung besteht darin, entweder einen Wert zu übergeben oder eine Increase<T> lokale Variable zu deklarieren und sie an V.traverse() weiterzuleiten.

+0

Danke! Jetzt verstehe ich den Schlüssel zu meinem Problem ist der temporäre r-Wert. – youyou