Home > Enterprise >  std::accumulate won't' perform sum of elements with std::plus functor
std::accumulate won't' perform sum of elements with std::plus functor

Time:10-25

I have a class which contains an integer among some other things:

class Foo
{
public:
    Foo() = default;
    Foo(int x)
        :
        x(x)
    {}
    int operator (const Foo& rhs)
    {
        return x   rhs.x;
    }
private:
    int x;
    float whatever = 0.0f;
};

I also have a vector of these objects:

std::vector<Foo> foos{1, 2, 3, 4};

now, what I wanted to do was to use std::accumulate with the std::plus functor (or maybe some other STL function) to sum the X values of all elements in the vector, here's what I tried:

int sum = std::accumulate(foos.begin(), foos.end(), 0, std::plus<int>{});

But i'm getting a compiler error

Error C2440: "'initializing' : cannot convert from 'type1' to 'type2' 'conversion' : cannot convert from 'type1' to 'type2'"

what am i doing wrong, how do I go about fixing this?

CodePudding user response:

You are trying to add an int and a Foo with a function that takes two Foos.

You could use a function that adds int to Foo:

// in Foo
friend int operator (int lhs, const Foo& rhs)
{
    return lhs   rhs.x;
}

Or you could use a function that adds two Foos

// in Foo
Foo operator (const Foo& rhs)
{
    return { x   rhs.x };
}

// in main
Foo sum = std::accumulate(foos.begin(), foos.end(), Foo(0), std::plus<Foo>{});

CodePudding user response:

you can implement operator as friend (free function), so int would auto convert to Foo in int Foo (because the constructor)


and do not use std::plus since you're now adding int and Foo, std::plus<T> only add two T and only returns T (i.e. it only has T operator()(const T&, const T&)const)


class Foo
{
public:
    Foo() = default;
    Foo(int x): x(x){}
    friend int operator (const Foo& lhs, const Foo& rhs){
        return lhs.x   rhs.x;
    }
private:
    int x;
    float whatever = 0.0f;
};


int f(){
    std::vector<Foo> foos{1, 2, 3, 4};
    // do not specify std::plus<int>
    // std::plus<Foo> would not work either since it returns `Foo`, not `int`
    return std::accumulate(foos.begin(), foos.end(), 0); 
}
  • Related