Why does 'for_each' not reading function object - c++

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template <class T>
class Sum {
public:
Sum(T i = 0) : res(i) {}
void operator()(T x) { res =res + x; }
T result() const { return res; }
private:
T res;
};
int main() {
Sum<int> s;
vector<int> vec;
vec.insert(vec.begin(), 10);
vec.insert(vec.begin()+1, 10);
vec.insert(vec.begin()+2, 10);
vector<int>::iterator itr = vec.begin();
cout << *itr << endl;
for_each(vec.begin(), vec.end(), s);
cout << "sum is" << s.result() << endl;
return 0;
}
This is my code. I want to add vec values in class Sum res. for_each should be calling s's operator(), so the result should be 30, but it shows 0.
I think adding value in vector has no problem. Why is the s.operator() is not working?

for_each takes its third argument by value which means every invocation of operator() affects a completely separate copy of s. There's an algorithm for exactly what you're doing called std::accumulate, but if you want this to work with for_each you need to pass s "by reference" by using std::ref from <functional>.
for_each(vec.begin(), vec.end(), ref(s));

for_each returns a copy of the passed-in functor that provides the "result" of the iteration (whatever the result is). Change your call to:
auto s = for_each(vec.begin(), vec.end(), Sum<int>());

Related

What is the meaning of bool operator () (int num)?

Is () used in the bool operator()(int num) of the below code a another operator or it means something else ? Please help.
#include <iostream>
#include <vector>
#include<algorithm>
using namespace std;
class IsOdd{
public:
bool operator()(int num){
return ((num%2)==1);
}
};
int main(){
vector <int> v {1,2,3,4,5,6,7,8,9,10};
vector <int>::iterator pend;
vector<int>:: iterator q;
pend = remove_if(v.begin(), v.end(), IsOdd());
for(q=v.begin(); q!=pend;++q)
cout<<*q<<endl;
return 0;
}
That means overloading the operator () to work with the IsOdd class.
Here is a sample of code of the overloaded operator in action:
#include <iostream>
#include <vector>
#include<algorithm>
class IsOdd {
public:
bool operator()(int num) {
return ((num % 2) == 1);
}
};
int main()
{
std::vector <int> v{ 1,2,3,4,5,6,7,8,9,10 };
IsOdd isOdd; // Defining object isOdd of the class IsOdd
for (int i = 0; i < v.size(); i++)
{
if (isOdd(v[i])) std::cout << v[i] << " is odd." << std::endl;
else std::cout << v[i] << " is not odd." << std::endl;
}
return 0;
}
I've also removed the iterators and shown with a much simpler way to iterate through elements in a std::vector.
Also, you should not use the following in your code:
using namespace std;
...as it's considered as bad practice.
Output:
1 is odd.
2 is not odd.
3 is odd.
4 is not odd.
5 is odd.
6 is not odd.
7 is odd.
8 is not odd.
9 is odd.
10 is not odd.
It's a function, and the () is part of the name - operator() is a special spelling for "function that is used to make an object behave like a function".
(It's a bit strange to call it "operator", but the C++ committee prefers reusing keywords to introducing new ones.)
If you have an object of the IsOdd type, such as
IsOdd is_odd;
then what looks like a regular function call,
is_odd(3)
is transformed behind the scenes into
is_odd.operator() (3)
IsOdd is a functor class. It has an overload of the function call operator, so that given an instance x you can call it via x(42) to determine if 42 is odd.
In the code it is used to pass a callable to the algorithm. Nowadays you would rather use a lambda:
auto isOdd = [](int x) { return ((num % 2) == 1);};
pend = remove_if(v.begin(), v.end(), isOdd);
or perhaps, if the functor is only needed for the algorithm but not elsewhere, define the lambda in-line:
pend = remove_if(v.begin(), v.end(), [](int x){ return ((num % 2) == 1);});
Is () used in the bool operator()(int num) of the below code a another operator or it means something else ?
Here:
pend = remove_if(v.begin(), v.end(), IsOdd());
the () in IsOdd() is a call to the constructor to create an instance of the class IsOdd. The operator() of that instance is then called by the algorithm. If you like you could also call it yourself:
auto x = IsOdd(); // call constructor
std::cout << x(42); // call operator()
It means it's a function named operator(), returns a boolean, and takes in an integer named num.
Edit:
Its an overloaded function operator so you can have it take no arguments or the argument int num.

Can we iterate through an array passed to a function using for-each loop?

I know we can iterate through an array passed as an argument in this way:
// NO ERROR
void fun(int *a, int n){
for(int i=0; i<n; i++)
cout<<a[i];
}
But, is there any way I could iterate through an array using a for-each loop inside a function like this?
// ERROR
void fun(int *a, int n){
for(auto x:a)
cout<<x;
}
A pointer is not an array. If you pass a pointer to the first element of an array to a function then its no longer an array, but a pointer.
You can use a range based loop when you pass the array by reference:
#include <iostream>
template <size_t N>
void foo(int (&x)[N]) {
for (int i : x) std::cout << i << " ";
}
int main() {
int x[] = {1,2,3};
foo(x);
}
Output:
1 2 3
This works, because the range based loop uses std::begin(x) and std::end(x) to get iterators to the begin and end of the array. Pointers don't have a begin or end.
In C++20, you can use std::span:
#include <cstddef>
#include <cstdio>
#include <span>
void foo(int* arr, std::size_t sz) {
std::span<int> span{arr, sz};
for (int elm : span) {
std::printf("%d\n", elm);
}
}
Or you could make span the input argument in the first place:
void foo(std::span<int> span) {
for (int elm : span) {
std::printf("%d\n", elm);
}
}
If the signature of the function is flexible, I suggest you use the second option.
Pre C++20, here is an implementation of span from GSL. Or make your own wrapper class with begin() and end() functions.
Alternative non-template C++20 solution:
auto range = std::views::counted(arr, sz);
for (auto elm : range) {
The benefit of this compared to std::span is that this is more general and works with any iterator, not requiring a contiguous iterator such as a pointer.
The benefit of using std::span instead of this is that you can use std::span as the function parameter without making it a template.
Alternative template solution (works pre C++20):
template <class Range>
void foo(const Range& range) {
for (auto elm : range) {
The benefit of this compared to int (&arr)[N] is that it is much more general. This template works with all ranges.
Besides range-for, you could consider avoiding the loop entirely (works pre C++20):
auto print = [](auto elm) {
std::cout << elm;
}
std::for_each_n(arr, sz, print);
I recommend this if you don't have C++20, cannot have boost / ranges / GSL libraries for some reason, and cannot have a template.
yes, you can. Just pass the array by reference to a template function:
#include <iostream>
using namespace std;
template <size_t N> void foo(int (&arr)[N])
{
for (auto i:arr)
cout << i << " ";
}
int main()
{
int array[] = { 5, 17, 3452, 546546, 756756, 75675, 756753, 345, 53};
foo(array);
return 0;
}
And the real answer:
int made[] = {10 , 2 ,15};
std::for_each(std::begin(made),std::end(made),[=](auto x){ std::cout << x << std::endl; });
You can parallelize std::for_each with say std::execution::par.
With function code will be:
#include <iostream>
#include <vector>
#include <execution>
void f(int (&made)[3])
{
std::for_each(std::begin(made),std::end(made),[=](auto x){ std::cout << "and then " << x << std::endl; });
}
int main(int argc , char *argv[])
{
int made[] = {10 , 2 ,15};
f(made);
}

Preserving insertion order on a std::set or std::unordered_set

Before marking this as duplicate, I have been here, here, and here, a duplicate of the first.
I'm aware of boost::multi_index, and use an environment where I lack it, and that a std::unordered_set is not bound to store elements in a deterministic insertion order.
I find the concept of using two containers, say an additional std::vector as uncouth.
What I would love is a solution involving a comparator that I can use in a std::set's template parameters (clarification, this could be a trivial functor struct, containing a bool operator()() overload, a regular function, or a lambda). Is it possible?
Addenda
Initialization must occur through a std:: container's begin iterator/end iterator constructor, such as in this snippet.
std::string str; cin >> str;
std::set<char>(str.begin(), str.end());
Also, another interesting use-case would be to create a dumb hash wrapping functor that allows insertion order to be pushed in to a std::unordered_set's template parameter.
You cannot directly have a lambda expression as the set's template parameter, because a lambda expression is a value, and the set's template parameter is a type. The obvious correction of the question, whether a construction using a lambda and decltype can work, leads to the interesting problem that a lambda expression denotes a unique type (a "closure type"), so you can never make two separate lambda expressions of the same closure type.*
However, in a more abstract sense what you want can be achieved in a local context using template argument deduction, for example:
template <typename F>
int f(int* first, int* last, F comp)
{
std::set<int, F> s(comp);
while (first != last) s.insert(*first++);
...
}
Now you can call f with a lambda expression as the argument, thus effectively "using a lambda as the set's comparator". Or, for a simpler example, you could just have a named variable for the lambda (putting all the template deduction into a single auto:
auto comp = [](...) { ... };
std::set<int, decltype(comp)> s(comp);
*) There is a proposal to allow lambdas in unevaluated contexts to address this point, but its outlook is uncertain. It has interesting side effects like making closure types affect name mangling.
An adt that preserves the order of insertion is an std::vector.
You can just as easily wrap it like this to get an std::set-like behavior:
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
using namespace std;
template < typename T >
class VectorSet : public vector<T> {
public:
using iterator = typename vector<T>::iterator;
using value_type = typename vector<T>::value_type;
pair<iterator, bool> insert (const value_type& val) {
auto it = ::find(this->begin(), this->end(), val);
if (it == this->end())
it = ::vector<T>::insert(this->end(), val);
return pair<iterator, bool>(it, true);
}
};
int main()
{
VectorSet<int> my;
my.insert(1);
my.insert(4);
my.insert(3);
my.insert(4);
for (auto & v : my) {
cout << v << endl;
}
return 0;
}
You cannot, unless you use additional indexes. Two approaches:
1. using an explicit index
Live On Coliru
#include <set>
#include <vector>
#include <functional>
#include <algorithm>
using namespace std;
#include <iostream>
string read_word() {
string str;
cin >> str;
return str;
}
int main() {
using Ref = std::reference_wrapper<char const>;
auto const str = read_word();
std::cout << "Word: " << str << "\n";
auto v = [&]() -> vector<Ref> {
set<Ref> u(str.begin(), str.end());
return {u.begin(), u.end()};
}();
std::cout << "Unique: " << string(v.begin(), v.end()) << "\n";
auto pos = [str](char ch) { return str.find(ch); };
std::sort(v.begin(), v.end(), [pos](auto& a, auto& b) { return pos(a) < pos(b); });
std::cout << "Insertion: " << string(v.begin(), v.end()) << "\n";
}
Prints e.g.
Word: pineapple
Unique: aeilnp
Insertion: pineal
2. using Boost Multi-Index
Same deal
Live On Coliru
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
namespace bmi = boost::multi_index;
using Index = bmi::multi_index_container<char,
bmi::indexed_by<
bmi::sequenced<>,
bmi::ordered_unique<bmi::tag<struct unique>, bmi::identity<char> >
> > ;
#include <iostream>
std::string read_word() {
std::string str;
std::cin >> str;
return str;
}
int main() {
auto const str = read_word();
std::cout << "Word: " << str << "\n";
Index idx(str.begin(), str.end());
std::cout << "Insertion: " << std::string(idx.begin(), idx.end()) << "\n";
auto& u = idx.get<unique>();
std::cout << "Unique: " << std::string(u.begin(), u.end()) << "\n";
}
Prints
Word: pineapple
Insertion: pineal
Unique: aeilnp
I thought a weird solution (though not one involving any sets) could be to use a std::map of the element type and std::time_point as the key type. That will ensure insertion order if not anything at all.

Initialise an Stl Vector of type T* from an array of type T

if I have an array such as:
struct S {... };
S m_aArr[256];
and I want to use this to construct a vector such as:
std::vector<S*> m_vecS;
Is there anyway to do this rather than looping through and pushing back &m_aArr[i] ?
I understand that I cannot use the conventional method of using std::begin and std::end on the array since the vector is one of pointers and the original array is one of objects, and so we cannot just pass in a block of memory.
You could use the standard library to do the iteration and pushing back for you:
std::transform(std::begin(m_aArr), std::end(m_aArr),
std::back_inserter(m_vecS), std::addressof<S>);
This will transform each of the elements in m_aArr by applying the std::addressof<S> function to them. Each of the transformed elements is then push_backed into m_vecS by the std::back_inserter iterator.
To do this prior to C++11, you won't have access to std::begin, std::end, or std::addressof, so it'll look more like this:
std::transform(m_aArr, m_aArr + 256, std::back_inserter(m_vecS), boost::addressof<S>);
This uses boost::addressof.
You could let std::transform perform the loop:
transform(std::begin(a), std::end(a), std::back_inserter(v),
[] (S& s) { return &s; });
Notice, that you do not need to fully qualify the name std::transform, because the function name will by found by ADL.
This is a complete program to test its behavior:
#include <iostream>
#include <vector>
#include <algorithm> // <== Required for std::transform
#include <iterator> // <== Required for std::back_inserter, std::begin, std::end
struct S
{
S() : i(0) { }
S(int i_) : i(i_) { }
int i;
};
int main()
{
S a[256] = { 42 }; // Copy-initializes first element from 42,
// default-constructs all other elements
std::vector<S*> v;
transform(std::begin(a), std::end(a), std::back_inserter(v),
[] (S& s) { return &s; });
std::cout << v.size() << std::endl; // Prints 256
std::cout << v[0]->i << std::endl; // Prints 42
std::cout << v[1]->i << std::endl; // Prints 0
}
And here is a live example.
A solution using std::generate_n() that performs the single allocation of the std::vector instead of potentially multiple via std::vector::push_back():
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main()
{
struct S {};
S a[128];
S* ap = a;
std::vector<S*> v(sizeof(a)/sizeof(a[0]));
std::generate_n(std::begin(v), v.size(), [&]() { return ap++; });
for (size_t i = 0; i < v.size(); i++)
{
if (&a[i] != v[i]) // Ensure same address at each element.
{
std::cerr << "Error\n";
break;
}
}
return 0;
}
See online at http://ideone.com/73nKST .

Why can't for_each modify its functor argument?

http://www.cplusplus.com/reference/algorithm/for_each/
Unary function taking an element in
the range as argument. This can either
be a pointer to a function or an
object whose class overloads
operator(). Its return value, if any,
is ignored.
According to this article, I expected that for_each actually modifies the object given as its third argument, but it seems like for_each operates on a temporary object, and doesn't even modify the object given to it.
So, why is it implemented in that way? It seems much less useful. Or did I misunderstand something and my code below contains errors?
#include <iostream>
#include <vector>
#include <algorithm>
template <class T> struct Multiplicator{
T mresult;
public:
const T& result() const{return mresult;}
Multiplicator(T init_result = 1){
mresult = init_result;
}
void operator()(T element){
mresult *= element;
std::cout << element << " "; // debug print
}
};
int main()
{
std::vector<double> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
Multiplicator<double> multiply;
std::for_each(vec.begin(),vec.end(),multiply);
std::cout << "\nResult: " << multiply.result() << std::endl;
return 0;
}
Expected output:
1 2 3 Result: 6
But got following output:
1 2 3 Result: 1
The function object is taken by value. for_each returns the function object, so if you change it to:
multiply = std::for_each(vec.begin(),vec.end(),multiply);
you get the expected output.
While James is correct, using std::accumulate with std::multiplies would be more correct, probably:
#include <iostream>
#include <functional>
#include <numeric>
#include <vector>
int main(void)
{
std::vector<double> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
double result = std::accumulate(vec.begin(), vec.end(),
1.0, std::multiplies<double>());
std::cout << "\nResult: " << result << std::endl;
}
With your for_each version, you don't really need to copy the functor again, rather:
double result = std::for_each(vec.begin(), vec.end(), multiply).result();
Or C++0x, for fun:
double result = 1;
std::for_each(vec.begin(), vec.end(), [&](double pX){ result *= pX; });
The semantics of For_each dont fit into what you are trying to do. accumulate does exactly what you are trying, use that instead.