Giriş
STL algoritmalarını işlevlerine göre gruplamak anlamayı çok daha kolaylaştırıyor.
for_each
Sadece algoritmayı göstermek için metodun içi şöyle düşünülebilir. Aslında return tipi void değil!
Paralel for_each
Şöyle yaparız.
Functor state tutabilir ancak functor'ın döndürdüğü değer kullanılmaz. Açıklaması şöyle.
Şu kod functor state tutmadığı için çalışmaz.
State tutan şöyle bir functor kodum olsun.
Daha kullanışlı bir örnek şöyle. Elimizde 0-9 arası değerler içeren bir vector olsun.
Yapılmaması Gerekekenler
for_each içinde silme yapılmamalıdır.
STL algoritmalarını işlevlerine göre gruplamak anlamayı çok daha kolaylaştırıyor.
for_each
Sadece algoritmayı göstermek için metodun içi şöyle düşünülebilir. Aslında return tipi void değil!
template <typename InputIterator, typename Functor>
void for_each(InputIterator first, InputIterator last, Functor f)
{
while (first != last) f(*first++);
}
Gerçek metodun içi ve imzası şöyle.template<typename _InputIterator, typename _Function>
_Function
for_each(_InputIterator __first, _InputIterator __last, _Function __f)
{
for (; __first != __last; ++__first)
__f(*__first);
return _GLIBCXX_MOVE(__f);
}
GCC'nin koduna karışmadan çok daha okunaklı bir gerçekleştirim şöyle.template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
for ( ; first!=last; ++first ) f(*first);
return f;
}
Verilen functor'ın kopyasını alır ve sonuç olarak döndürür. Sonuç olarak functor nesnesi döndürdüğü için functor içinde state tutabilir.Paralel for_each
Şöyle yaparız.
std::for_each(std::execution::par_unseq, std::begin(indices), std::end(indices),
[&](std::size_t const i) { ... });
Functor State TutabilirFunctor state tutabilir ancak functor'ın döndürdüğü değer kullanılmaz. Açıklaması şöyle.
ÖrnekIf f returns a result, the result is ignored.
Şu kod functor state tutmadığı için çalışmaz.
vector<string> v;
if(not for_each(v.begin(), v.end(), [](const string& str) -> bool{
...;
})
);
ÖrnekState tutan şöyle bir functor kodum olsun.
class MyFunctor
{
Y val;
public:
MyFunctor() : val() {}
void operator()( X const& x )
{
// do something to modify val based on x
}
Y getValue() const { return val; }
};
Bu functor'ı for_each ile kullanarak val değerini güncellerim ve nihai sonucu şöyle alırım.Y y = for_each( coll.begin(), coll.end(), MyFunctor() ).getValue();
ÖrnekDaha kullanışlı bir örnek şöyle. Elimizde 0-9 arası değerler içeren bir vector olsun.
std::vector<int> vec =
{1,2,3,4,5,6,7,8,9};
Bu değerli toplayan bir sınıf yazalım.template <class T>
class Sum {
private:
T val;
public:
Sum (T i = 0) : val(i) {
}
void operator()(T x) {
val += x;
}
T result() const {
return val;
}
};
for_each sonuç döndüğü için toplam işleminin sonucunu şöyle alabiliriz.Sum<int> s1 = std::for_each(vec.begin(), vec.end(), s);
Bu durumda 0'dan 9'a kadar olan sayıların toplamını alırız.Yapılmaması Gerekekenler
for_each içinde silme yapılmamalıdır.
std::for_each(set.begin(), set.end(),
[&map](const std::string & s) { map.erase(s); });
Hiç yorum yok:
Yorum Gönder