for_each w wersji z UnaryFunction , jak to działa ?

0

Dlaczego w tym przypadku Sum() nie uruchamia konstruktora dla każdego elementu ?
Czy taka konstrukcja trochę nie jest myląca ?

#include <vector>
#include <iostream>
#include <algorithm>

int main()
{
    struct Sum
    {
        Sum()
        {
            std::cout << "Sum::Sum()\n";
        }
        Sum(const Sum& a) : sum(a.sum) {
            std::cout << "Sum::Sum(const Sum& a)\n";
        } 
        void operator()(int n)
        {
            sum += n;
        }

        int sum {0};
    };

    std::vector<int> v {3, -4, 2, -8, 15, 267};
    // invoke Sum::operator() for each element
    Sum s = std::for_each(v.cbegin(), v.cend(), Sum());
    std::cout << "sum:\t" << s.sum << '\n';
}  
4

Mylące jest użycie for_each zamiast std::accumulate...

Możesz to sobie tak zapisać:

//         = Sum() tylko po to, żeby było widać gdzie to jawne wywołanie konstruktora się podziało
// Sum tmp = Sum();
Sum tmp;
Sum s = std::for_each(v.cbegin(), v.cend(), tmp);

i dalej

Sum tmp;
for (auto &e: v)
  tmp(v);

Sum s = tmp;
1

Ale o który element Ci chodzi? O obiekt "Sum s"?
Tworzysz go raz i tyle. Potem wywoluejsz operator() za każdym razem w pętli.

A na odpowiedź czy jest myląca to tak, jest mega myląca i przekombinowana.

3

Bo przekazujesz do algorytmu obiekt, a nie przepis na jego konstruowanie.
Najpierw konstruujesz obiekt tymczasowy Sum() bezpośrednio jako wartość argumentu for_each (parametr przekazany przez wartość).
Potem ten sam obiekt jest zwracany przez wartość zwracaną, dlatego wykonywana jest kopia.
https://godbolt.org/z/P3ox6hvo5

Sum::Sum()
Sum::Sum(const Sum& a)
sum:	275

std::for_each - cppreference.com

Possible implementation

See also the implementations in libstdc++, libc++ and MSVC stdlib.

template<class InputIt, class UnaryFunction>
constexpr UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f)
{
    for (; first != last; ++first)
        f(*first);
 
    return f; // implicit move since C++11
}
0
Marius.Maximus napisał(a):

Dlaczego w tym przypadku Sum() nie uruchamia konstruktora dla każdego elementu ?

Bo tak działa przekazywanie argumentów do funkcji. Jak chcesz mieć kopię to zrób sobie bezstanową lambdę

0

Mea culpa ! dojrzałem jak to działa :D
wszystko już jasne, dziękuje !
zafiksowałem się na błędny koncept

1 użytkowników online, w tym zalogowanych: 0, gości: 1