2010-10-07 8 views

Odpowiedz

73

Tak, używając std::transform:

std::transform(myv1.begin(), myv1.end(), myv1.begin(), 
       std::bind1st(std::multiplies<T>(),3)); 
+0

Wielkie dzięki, że to geniusz !! –

21

Jeśli możesz użyć valarray zamiast vector, ma wbudowane operatory do wykonywania mnożenia skalarnego.

v *= 3; 

Jeśli trzeba użyć vector można rzeczywiście korzystać transform aby wykonać zadanie:

transform(v.begin(), v.end(), v.begin(), _1 * 3); 

(zakładając, że masz coś podobnego do Boost.Lambda, który pozwala na łatwe tworzenie anonimowych obiektów funkcyjnych takich jak _1 * 3 :-P)

+1

Valarrays są poprawnym rozwiązaniem IMO. Przy odrobinie szczęścia twoja implementacja używa instrukcji SSE do implementacji procedury, co znacznie przyspiesza. Zobacz http://www.pixelglow.com/macstl/valarray/ dla jednej z takich realizacji valarray. Niestety, nie jest to zbyt rozpowszechnione, więc jeśli chcesz mieć zalety instrukcji SSE, prawdopodobnie będziesz musiał użyć wbudowanego kompilatora ... – Dragontamer5788

+0

@Dragon: 'valarray' jest najlepszym rozwiązaniem STL, ale nie jest zbyt dobre dla wysokiej wydajności przetwarzanie, ponieważ ma tendencję do częstego kopiowania danych w pamięci i tworzy sekwencje małych pętli zawierających pojedyncze operacje, które mają słabe wzorce dostępu do pamięci. Łatwiej jest jednak dokonać aktualizacji z 'valarray' do odpowiedniego systemu szablonów wyrażeń. – Potatoswatter

0

Po prostu: jeśli dane mogą być przechowywane w macierzy o ustalonej wielkości (wartości zmiennoprzecinkowe [N]), można użyć indeksu wewnętrznego SSE, aby przyspieszyć, ponieważ będzie ono mnożyć zmienną sevreral (4).

0

Wiem, że nie STL, jak chcesz, ale jest to coś, co można dostosować, gdy pojawiają się różne potrzeby.

Poniżej znajduje się szablon, którego można użyć do obliczenia; "func" będzie funkcją, którą chcesz zrobić: mnożyć, dodawać itd .; "parm" to drugi parametr funkcji "func". Możesz łatwo rozszerzyć to, aby uzyskać różne funkcje z większą ilością różnych rodzajów parm.

template<typename _ITStart, typename _ITEnd, typename _Func , typename _Value > 
_ITStart xform(_ITStart its, _ITEnd ite, _Func func, _Value parm) 
{ 
    while (its != ite) { *its = func(*its, parm); its++; } 
    return its; 
} 
... 

int mul(int a, int b) { return a*b; } 

vector<int> v; 

xform(v.begin(), v.end(), mul, 3); /* will multiply each element of v by 3 */ 

Ponadto nie jest to funkcja "bezpieczna", należy przed jej użyciem wykonać sprawdzanie typu/wartości itp.

+0

To działa, ale jest w istocie odkrywaniem koła, ponieważ 'std :: transform' już to robi dla ciebie. –

+0

Tak - widziałem w zaakceptowanej odpowiedzi ... ale czy zdajesz sobie sprawę, jaką przyjemność sprawia wynalezienie koła, które faktycznie działa;) W każdym razie zastrzelę siebie w dniu, w którym zostanę konformistą;) – slashmais

0

myślę for_each jest bardzo trafne, gdy chcesz przemierzać wektor i manipulować każdy element według pewnego wzorca, w tym przypadku proste lambda wystarczyłby:

std::for_each(myv1.begin(), mtv1.end(), [](int &el){el *= 3; }); 

uwagę, że każda zmienna chcesz uchwycić dla funkcji lambda (powiedzmy, że chcesz np. pomnożyć się z pewnym z góry określonym skalarem), przechodzi do nawiasu jako odniesienie.

+0

To nie jest celem std :: for_each'. 'std :: for_each' stosuje pewien (prawdopodobnie stanowy) obiekt funkcji do zakresu, a następnie zwraca ten obiekt funkcji. Jeśli chcesz przekształcić zakres, użyj 'std :: transform', aby twoje intencje były wyraźniejsze. – sv90

Powiązane problemy