2013-08-08 14 views
5

Tut mir leid, wenn diese Frage Verwirrung stiftet, ich suche, dies zu implementieren und nicht den richtigen Weg, um so etwas zu nähern.Methode Verkettung von Namespace

Für eines meiner Projekte möchte ich Methodenverkettung implementieren. Ich möchte die folgenden Funktionen zu übernehmen:

.toVector() 
.toArray() 
.toBool() 
... 

Ich habe darüber nachgedacht, diese innerhalb eines Namensraumes platzieren, zum Beispiel:

namespace Misc { 
    template<typename T, typename Inverse> 

    vector<T> toVector(Inverse begin, Inverser end) { 
     // ... 
     // .. 
    } 

    // ... 
    // ... 
} 

Das ist, weil es mehrere Klassen sein könnte, könnten diese Klassen der Lage sein, zu verwenden, Diese Funktionen müssen also OO sein, anstatt jede Funktion immer wieder in verschiedenen Klassen zu implementieren.

Lassen Sie uns sagen, dass ich die folgende Klasse Wav haben, die in den Daten liest in einer WAV-Datei enthalten:

class Wav { 
    public: 
    Wav(); 
    Wav(string theFileName); 
    void getWaveData(); 
    protected: 
    vector<double> data; 
}; 

data explizit als Vektor innerhalb der Klasse gespeichert ist.

In meinem Haupt mag ich in der Lage sein, Folgendes zu tun:

int main() 
{ 
    Wav wave("file.wav"); 

    int* data = wave.getWaveData().toArray(); // Method chaining to store as an array 
} 

Ich weiß nicht, ob dies möglich wäre, und wenn ja, wie ich diesen Ansatz ohne all die Misc Funktionen Implementierung immer und immer wieder in jeder der Klassen. Gibt es eine Möglichkeit, zwischen dem Namespace und der Klasse zu kommunizieren, ohne alle Funktionen wieder und wieder einfügen zu müssen?

Ich hoffe, jemand hat einen Vorschlag und alle Fragen werde ich versuchen zu beantworten.

EDIT:

Ich habe das geschrieben die folgende Funktion:

template<typename T, typename Inverse> 
T* toArray(Inverse begin, Inverse end) 
{ 
size_t size = distance(begin, end); 
auto pos = 0; 

T* tmp = new T[size]; 

for(auto i = begin; i != end; i++) 
{ 
    tmp[pos] = *i; 
    pos++; 
} 
return tmp; 
} 

Und wenn ich eine andere Funktion:

void process() 
{ 

} 

Was würde ich daher in der params setzen müssen von process, um Folgendes zu akzeptieren:

int* data = process(toArray<int>( std::begin(vals), std::end(vals) );

Das ist die Sache, die mich am meisten verwirrt?

+2

Warum muss es Kettenverkettung sein? Wenn Sie nach (möglicherweise verschachtelten) Funktionsaufrufen suchen, wäre das trivial. – delnan

+0

@delnan Könnten Sie bitte ein Beispiel dafür geben, was Sie meinen? – Phorce

+2

'toBool (toArray (wave.getWaveData()))' anstelle von 'wave.getWaveData(). ToArray(). ToBool()'. – delnan

Antwort

2

In Bezug auf Ihre neue Funktion:

Um den Prozess Methode aufrufen zu können, unter

int* data = process(toArray<int>(vals.begin(), vals.end())); 

den Parameter für die Prozessmethode sollte den Rückgabetyp des toArray Methode entsprechen. Vielleicht können Sie auch die Prozessmethode wie unten beschrieben templatisieren.

template<typename T> 
T* process(T* t) 
{ 
    //more code here 
    return t; 
} 

den Prozess Verfahren wie oben Nach der Zugabe wird der Anruf zu verarbeiten kompilieren, aber Sie werden die Durchführung der Verfahrens Methode generisch genug, um mit unterschiedlichen Rückgabetypen von anderen Methoden wie toArray zu machen.