2016-04-03 9 views
1

Dies ist eine Folgefrage an my previous one. Ich baue eine Array-Klasse mit grundlegenden Vektor-Mathematik-Funktionalität. Ich möchte eine Funktion definieren, die es einem Benutzer ermöglicht, eine beliebige Funktion über das gesamte Array abzubilden. Ich kann dies bereits für vordefinierte binäre Funktionen tun (z. B. operator+= für direkte Ergänzung), aber ich habe Mühe zu sehen, wie dies für eine beliebige Anzahl von Eingaben getan werden könnte.Anwenden einer Funktion über eine beliebige Anzahl variadischer Argumente

template<typename T, size_t ... Ns> 
class Array 
{ 
public: 
    Array() { /* allocate memory of size product(Ns) * sizeof(T) */ } 

    ~Array() { /* deallocate memory */ } 

    inline Array<T, Ns...>& operator+=(const Array<T, Ns...> &rhs)     
    { 
     // simple case: predefined operation on exactly two Arrays 
     T *p1 = data, *p2 = rhs.data;             
     while (p1 != data + size) { *p1 += *p2; p1++; p2++; }                    
     return *this;                 
    } 

    template<class ... Args> 
    inline const Array<T, Ns...> map(T (*fn)(arg_type<Args>...), Args ... args) 
    { 
     // difficult case: arbitrary operations on a variable number of Arrays 
    } 

    private: 
     T *data; 
     size_t size; 
} 

// example usage 
double f(double a, double b) { return a + b; } 
Array<double,2> x, y, z; 
x.map(f, y, z); 

ich so etwas zu Schleife über alle Elemente in y und z, Anwendung f zu ihnen, und deren Speicherung in x wünschen würde. Ich dachte, ich könnte es auf meine operator+=-Funktion modellieren, aber ich habe noch keine Parameter-Pack-Erweiterung gefunden, die mich etwas ähnliches (und kompilieren) lassen würde. diese

+0

Im Kern würden Sie etwas sagen wie '(data [I] = f (args [I] ...)) ...', was in einer Hilfsfunktionsvorlage passieren sollte, die ein 'braucht index_sequence 'und' Args ... args', nehme ich an. –

+0

ist "Daten" immer eindimensional (d. H. "Ns" enthält immer einen einzigen Wert)? –

+0

Ersetzen Sie Daten und Größe mit einem Vektor von T. Schreiben Sie Code, der N Vektoren übernimmt und eine Funktion über alle von ihnen anwendet, einen Vektor des Ergebnisses zurückgebend. Schreiben Sie einen Konstruktor für Ihre Arrray-Klasse, der einen Vektor enthält. Verfassen Sie diese Lösungen, lösen Sie Ihr Problem (und hören Sie damit auf, die Leadspace-Verwaltung von rohen Zeigerlebenszeiten zu verschwenden!) – Yakk

Antwort

0

schreiben:

template<class T, class Array2> 
using Array_Size_Copy = // expression that creates a Array<T,???>, where ??? is the Ns... of Array2 above 

dann

template<class F, class A0, class...Arrays> 
auto array_apply(F&& f, A0&& a0, Arrays&&...arrays) { 
    using R = decay_t<decltype(f(std::declval<A0>().data.front(), std::declval<Arrays>().data.front()...))>; 

    Array_Size_Copy<R, std::decay_t<A0>> retval; 

    for (int i = 0; i < a0.size(); ++i) { 
    retval.data[i] = f(std::forward<A0>(a0).data[i], std::forward<Arrays>(arrays).data[i]...); 
    } 
    return retval; 
} 

In einigen behauptet (statisch behauptet im Idealfall), dass alles gleich groß ist.

Die obige Funktion muss möglicherweise ein Freund sein. Das bedeutet, dass Sie möglicherweise den Rückgabewert festlegen müssen, anstatt auto zu verwenden, aber das ist nur der Typ Gymnastik in die Deklaration.

Verwandte Themen