2016-06-17 13 views
1

Der Code ist wie folgt:Was ist der Punkt des make_transform_iterator als zweiter Parameter im Schub :: reduzieren Algorithmus?

thrust::reduce(thrust::make_transform_iterator(v.begin(), square()), 
        thrust::make_transform_iterator(v.end(), square())); 

here von transform_iterator Beispiel genommen. Insbesondere, ist es nicht überflüssig, das Folgende als zweiten Iterator zu verwenden?

thrust::make_transform_iterator(v.end(), square()) 

Warum nicht einfach das Folgende an seiner Stelle verwenden?

thrust::reduce(thrust::make_transform_iterator(v.begin(), square()), 
        v.end()); 

ich in diesem speziellen Beispiel nehme an, da thrust::make_transform_iterator(v.begin(), square()) keinen Iterator erzeugen, die als v unterschiedlicher Größe, mein aktualisierten Code das gleiche wie das Original tun würde, ist das richtig?

EDIT
Meine einzige Vermutung ist, dass es beide Iteratoren vom gleichen Typ sind, um sicherzustellen, ist? Alles was ich fand, um meinen Verdacht zu bestätigen, war der folgende Text in der Dokumentation: "Der Transformations-Funktor (nämlich Quadratwurzel und Quadrat) erbt von Schub :: unary_function. Das Erben von Schub :: unäre_funktion stellt sicher, dass ein Funktor eine gültige AdaptableUnaryFunction ist und alle bereitstellt die notwendigen typedef-Deklarationen. " Obwohl ich denke, das bezieht sich speziell auf den Funktor selbst.

UPDATE
Siehe Robert Crovella Kommentar für Antwort.

+3

Die hier Iteratoren werden verwendet, um den Anfang zu markieren und einer spezifischen Sequenz endet. v.end markiert nicht das Ende der Sequenz, für die der Transformations-Iterator den Anfang von markiert. –

+0

Oh, ich weiß nicht, warum ich darum gekämpft habe, das zu begreifen. Ich denke, das Schlüsselwort ist eine "spezifische" Sequenz. Es muss auf denselben Ort im Gedächtnis zeigen. 'v.end()' ist nicht dieselbe Endposition im Speicher wie die Endposition des Iterators, die durch 'schub :: make_transform_iterator (v.begin(), square())' erstellt wurde. Vielen Dank! – aiwyn

+3

Sie könnten auch 'schub :: make_transform_iterator (v.begin(), square()) + v.size()' verwenden. Es sieht vielleicht intuitiver aus. – kangshiyin

Antwort

1

Die Iteratoren hier werden verwendet, um den Anfang und das Ende einer bestimmten Sequenz zu markieren. v.end() nicht das Ende der Sequenz markiert, die den Iterator hier verwandeln:

thrust::reduce(thrust::make_transform_iterator(v.begin(), square()), 
       v.end()); 

markiert den Start.

Einige andere Konstrukte hier könnte ein besseres Aussehen haben (Schönheit liegt im Auge des Betrachters), wie zum Beispiel:

auto my_iter = thrust::make_transform_iterator(v.begin(), square()); 
thrust::reduce(my_iter, my_iter+v.size());