In C++, how to iterate array in reverse using for_each? - c++11

In C++11, using lambda/for_each, how do we iterate an array from end?
I tried the following, but both result in infinite loop:
for_each (end(A), begin(A), [](int i) {
....
});
for_each (A.rend(), A.rbegin(), [](int i) {
...
});
Any idea? Thanks.

You missed this ?
Flip your rbegin & rend
for_each (A.rbegin(), A.rend(), [](int i) {
...
});
Increasing reverse iterator moves them towards the beginning of the container

std::for_each( A.rbegin(), A.rend(), [](int i) { /*code*/ } ); is the simple solution.
I instead have written backwards which takes a sequence, extracts the begin and end iterator from it using the free begin and end functions (with std::begin and std::end using declarations nearby -- full ADL), creates reverse iterators around them, then returns a sequence with those two reverse iterators.
It is sort of neat, because you get this syntax:
for( int i : backwards(A) ) {
// code
}
which I find easier to read than std::for_each or manual for loops.
But I am a bit nuts.
Here is a minimal backwards. A full on solution handles adl and a few corner cases better.
template<class It, class C>
struct range_for_t{
It b,e;
C c; // for lifetime
It begin()const{return b;}
It end()const{return e;}
}
template<class It, class C>
range_for_t<It,C> range_for(It b,It e,C&& c){
return {std::move(b),std::move(e),std::forward<C>(c)};
}
template<class It>
range_for_t<It,int> range_for(It b,It e){
return {std::move(b),std::move(e)};
}
A simple range for range for only. Can be augmented with perfect forwarding.
Passing C as the container that may need lifetime extending. If passed as rvalue, copy is made, otherwise just reference. It is otherwise not used.
Next part is easy:
template<class It>
auto reverse_it(It it){
return std::reverse_iterator<It>(std::move(it));
}
template<class C>
auto backwards(C&&c){
using std::begin; using std::end;
auto b=begin(c), e=end(c);
return range_for(
reverse_it(e),reverse_it(b),
std::forward<C>(c)
);
}
That is untested but should work.
One important test is ensuring it works when you feed an rvalue vec like:
for(auto x:backwards(make_vec()))
works -- that is what the mess around storing C is about. It also assumes that moved container iterators have iterators who behave nicely.

Boost offers a feature named reversed, that can be used with C++ 11 range based for loop as describes Yakk in his answer:
for(int i : reverse(A))
{
// code
}
or
for(int i : A | reversed)
{
// code
}

Since C++20, there is a convenient adaptor for this:
#include <ranges>
...
for (auto& element: container | std::views::reverse)
For example:
#include <iostream>
#include <ranges>
#include <vector>
int main()
{
std::vector<int> container {1, 2, 3, 4, 5};
for (const auto& elem: container | std::views::reverse )
{
std::cout << elem << ' ';
}
}
// Prints 5 4 3 2 1
Try it here:
https://coliru.stacked-crooked.com/a/e320e5eec431cc87

Related

C++11 container of borrowed unique_ptrs

I have a vector of unique_ptrs and want to filter it into a new vector of the same type.
vector<unique_ptr<Thing>> filter_things(const vector<unique_ptr<Thing>> &things) {
vector<unique_ptr<Thing>> things;
// i want the above line to be something like: vector<const unique_ptr<Thing> &>
// but I don't think this is valid
for (const unique_ptr<Thing> &thing : things) {
if (check(thing)) {
filtered.push_back(thing); // this part shouldn't work since it
// would duplicate a unique_ptr
}
}
return filtered;
}
I want the caller to maintain ownership of all the Things. I want the return value of this function to be purely read only (const), and I don't want to make copies as it is very expensive to copy a Thing.
What is the best way to accomplish this?
Is this possible with unique_ptrs?
In some sense, we are creating multiple references by returning a new vector of references, so unique_ptr may not make sense. However, it is purely read only! So there should be some way to make this work. The lifetime of ``things'' is guaranteed to be larger than the filtered things.
Note that the caller owns the parameter supplied.
You can use reference_wrapper from <functional>
#include <memory>
#include <functional>
#include <vector>
#include <iostream>
using namespace std;
struct Thing {};
using PThing = unique_ptr<Thing>;
using RefThing = reference_wrapper<const PThing>;
vector<RefThing> filter_things( const vector<PThing>& things )
{
vector<RefThing> filtered;
int i = 0;
for( auto&& thing : things )
{
if( i++%2 )
filtered.push_back( ref(thing) );
}
return filtered;
}
int main()
{
vector<PThing> vec;
vector<RefThing> flt;
vec.resize(25);
flt = filter_things(vec);
cout << flt.size() << endl;
}
If what you want is getting a filtered set of element not an actual container containing them, boost::range can be a good solution.
auto filtered_range(const std::vector<std::unique_ptr<Thing>> &things) {
return things | boost::adaptors::filtered([](const auto& thing) {
return check(thing);
});
}
I used some of c++14 syntax but I don't think it's hard to make it to c++11.
You can use it like this.
std::vector<std::unique_ptr<Thing> > things;
for(const auto& thing : filtered_range(things)) {
// do whatever you want with things satisfying 'check()'
}
One of disadvantages is that the range itself is not a container so if you traverse the range more than once, every 'thing' will be checked if it satisfies check().
If a container storing the checked things AND controlling the lifetime of things are what you really want, I would prefer using std::vector<std::shared_ptr<Thing> > and returning std::vector<std::weak_ptr<Thing> >. You can check if it's really one and the only ptr to a thing with std::shared_ptr::unique() before deleting it from things.

std::string::assign vs std::string::operator=

I coded in Borland C++ ages ago, and now I'm trying to understand the "new"(to me) C+11 (I know, we're in 2015, there's a c+14 ... but I'm working on an C++11 project)
Now I have several ways to assign a value to a string.
#include <iostream>
#include <string>
int main ()
{
std::string test1;
std::string test2;
test1 = "Hello World";
test2.assign("Hello again");
std::cout << test1 << std::endl << test2;
return 0;
}
They both work. I learned from http://www.cplusplus.com/reference/string/string/assign/ that there are another ways to use assign . But for simple string assignment, which one is better? I have to fill 100+ structs with 8 std:string each, and I'm looking for the fastest mechanism (I don't care about memory, unless there's a big difference)
Both are equally fast, but = "..." is clearer.
If you really want fast though, use assign and specify the size:
test2.assign("Hello again", sizeof("Hello again") - 1); // don't copy the null terminator!
// or
test2.assign("Hello again", 11);
That way, only one allocation is needed. (You could also .reserve() enough memory beforehand to get the same effect.)
I tried benchmarking both the ways.
static void string_assign_method(benchmark::State& state) {
std::string str;
std::string base="123456789";
// Code inside this loop is measured repeatedly
for (auto _ : state) {
str.assign(base, 9);
}
}
// Register the function as a benchmark
BENCHMARK(string_assign_method);
static void string_assign_operator(benchmark::State& state) {
std::string str;
std::string base="123456789";
// Code before the loop is not measured
for (auto _ : state) {
str = base;
}
}
BENCHMARK(string_assign_operator);
Here is the graphical comparitive solution. It seems like both the methods are equally faster. The assignment operator has better results.
Use string::assign only if a specific position from the base string has to be assigned.

Merge two Boost Fusion maps based on keys

I have two boost::fusion::maps that I want to merge in a certain way. For the two maps I want to generate a third that has all the keys present in both maps and the values are added if both a present. For example:
#include <boost/fusion/container/map.hpp>
namespace bfn = boost::fusion;
using namespace boost::fusion;
struct x{};
struct y{};
struct z{};
int main(){
auto m = make_map<x, y>(2, 4.3);
auto n = make_map<x>(2.);
auto l = accumulate_merge(m, n); // how this function should look like?
}
After that l will be equivalent to make_map<x, y>(2 + 2., 4.3).
I have no clue where to start. I tried to begin with join (and the eliminate duplicates but I got complicated pretty fast).
Is there a tool in Boost Fusion that can help me?
(There are lots of subtleties like what to do if for the same key the two corresponding types are different --but still addable--. But any first version will help).
I managed to come up with this version using boost::fusion::fold twice. I am not sure if it is (compile-time) optimal.
Basically, I iterate first over the first map. If the key is not in the second map the element is pushed to the result. If the key is in the second map the elements are added and the result (whatever the type is pushed to the result).
Finally, I iterate in the second map. If the key is in the first map I ignore it (because it was added in the first pass). If the key is not in the second the element is pushed to the result.
(The result is that the first map has precedence for the ordering of the key types)
There are some open issues or doubts:
1) there is a more efficient/compact way of doing this
2) I wasn't sure about the use of forward basically I used it everywhere (just in case)
3) not sure about the auto vs. decltype(auto) in the function returns.
4) The functions are not SFINAE friendly, I could add guards to generate soft errors. (For example if values cannot be added).
5) The result doesn't have any natural order, I don't know if this is a problem with the algorithm or with fold or because map don't specify an order with push_back (after all it is a map).
Comments are welcome.
Now the code:
namespace boost{
namespace fusion{
namespace detail{
template<class Map2>
struct merge1{
Map2 m2_;
template<typename MapOut, typename Pair1>
auto operator()(MapOut&& mo, Pair1&& p1) const{
return conditional_push_back(std::forward<MapOut>(mo), std::forward<Pair1>(p1), has_key<typename std::decay_t<Pair1>::first_type>(m2_));
}
template<typename MapOut, typename Pair1>
auto conditional_push_back(MapOut&& mo, Pair1&& p1, mpl_::bool_<false>) const{
return push_back(std::forward<MapOut>(mo), std::forward<Pair1>(p1));
}
template<typename MapOut, typename Pair1>
auto conditional_push_back(MapOut&& mo, Pair1&& p1, mpl_::bool_<true>) const{
return push_back(std::forward<MapOut>(mo), make_pair<typename std::decay_t<Pair1>::first_type>(p1.second + at_key<typename std::decay_t<Pair1>::first_type>(m2_)));
}
};
template<class Map2>
merge1<Map2> make_merge1(Map2&& m2){return {std::forward<Map2>(m2)};}
template<class Map1>
struct merge2{
Map1 m1_;
template<typename MapOut, typename Pair2>
auto operator()(MapOut&& mo, Pair2&& p2) const{
return conditional_push_back(std::forward<MapOut>(mo), std::forward<Pair2>(p2), has_key<typename std::decay_t<Pair2>::first_type>(m1_));
}
template<typename MapOut, typename Pair2>
auto conditional_push_back(MapOut&& mo, Pair2&& p2, mpl_::bool_<false>) const{
return push_back(std::forward<MapOut>(mo), std::forward<Pair2>(p2));
}
template<typename MapOut, typename Pair2>
auto conditional_push_back(MapOut&& mo, Pair2&& , mpl_::bool_<true>) const{
return mo;
}
};
template<class Map1>
merge2<Map1> make_merge2(Map1&& m){return {std::forward<Map1>(m)};}
}
template<class Map1, class Map2>
inline auto accumulate_merge(Map1&& m1, Map2&& m2){
return
as_map( // not completely sure this is a good idea
fold( // second map2 is checked for unpaired elements
std::forward<Map1>(m1),
fold( // first map1 takes the lead
std::forward<Map2>(m2),
make_map<>(),
detail::make_merge1(std::forward<Map1>(m1))
),
detail::make_merge2(std::forward<Map2>(m2))
)
);
}
}}
namespace bfn = boost::fusion;
using namespace boost::fusion;
struct x{};
struct y{};
struct z{};
int main(){
auto m = make_map<x, y >(2, 4.3 );
auto n = make_map< y, z>( 2 , 8.);
auto l = accumulate_merge(m, n);
assert( at_key<x>(l) == at_key<x>(m) );
assert( at_key<y>(l) == at_key<y>(m) + at_key<y>(n) );
assert( typeid(at_key<y>(l)) == typeid(at_key<y>(m) + at_key<y>(n)) );
assert( at_key<z>(l) == at_key<z>(n) );
}

How to store functional objects with different signatures in modern C++

I would like to know if there is a way to store functional objects (functions, callbacks, ...) with different signatures in a standard container (std::map) with modern C++ only. The library that manages the container does not know which signatures will be used by its "clients".
My need is the same as exposed here : How to store functional objects with different signatures in a container?, and this solution https://stackoverflow.com/a/8304873/4042960 is about perfect for me: I would just like to do the same thing without boost. As far as I know, there is no std::any. The best solution for me would be to store std::function without specialized them, but I do not know how to do it, if it is possible.
Edit:
With the answers you give to me I wrote this example :
#include <map>
#include <memory>
#include <functional>
#include <string>
#include <iostream>
#include <stdexcept>
class FunctionMap
{
struct Base {
virtual ~Base() {}
};
template<class R, class... Args>
struct Func : Base
{
std::function<R(Args...)> f;
};
std::map<std::string, std::shared_ptr<Base> > _map;
public:
template<class R, class... Args>
void store(const std::string &key, const std::function<R(Args...)> &f) {
auto pfunc = std::make_shared<Func<R, Args...> >();
pfunc->f = f;
_map.insert(std::make_pair(key, pfunc));
}
template<class R, class... Args>
std::function<R(Args...)> get(const std::string &key) {
auto pfunc = std::dynamic_pointer_cast<Func<R, Args...> >(_map[key]);
if (pfunc)
return pfunc->f;
else
throw std::runtime_error("Bad type for function's parameters");
}
};
// test
int plus(int a, int b) { return a+b; }
double multiplies(double x, double y) { return x*y; }
int main()
{
FunctionMap fm;
fm.store("plus", std::function<int(int, int)>(&plus));
fm.store("multiplies", std::function<double(double, double)>(&multiplies));
// fm.store("square", std::bind(&multiplies, std::placeholders::_1, std::placeholders::_1));
std::cout << "5 + 3 = " << fm.get<int, int, int>("plus")(5, 3) << std::endl;
std::cout << "5 * 3 = " << fm.get<double, double, double>("multiplies")(5.0, 3.0) << std::endl;
return 0;
}
This works well, but I would like to improve it a bit:
1) I would like to be able to use std::bind : fm.store("square", std::bind(&multiplies, std::placeholders::_1, std::placeholders::_1)); but currently that does not compile ;
2) I would like to use fm.get<int (int, int)>("plus") instead of fm.get<int, int, int>("plus") but I do not know how to do it.
Many thanks for your help !
You can write your own any. Without all the compiler workarounds and stuff, boost::any can be written in about 30 lines of code.
Function objects are in no way different from any other kind of objects, so anything applicable to objects in general is applicable to function objects.
So you want to store different kinds of (function) objects in a map. This is normally done by storing (smart) pointers to a base class, where each derived class holds its own kind of objects you want to store.
struct Base {
virtual ~Base(){}
};
template <typename A>
struct Object : Base {
A value;
};
That's your basic caveman's boost::any. Your clients do something like this:
Base* b = mymap["foo"];
dynamic_cast<Object<void(*)(int)>*>(b)->val(123);
But with appropriate checks of course.

C++ lambdas passing

This is just theoretical question. When i execute this code:
#include <functional>
#include <cstdio>
struct A {
int value = 100;
A() {
printf("A\n");
}
A(const A& a) {
printf("copy A\n");
}
~A() {
printf("~A\n");
}
};
void function(std::function<int()> lambda) {
printf("%d\n", lambda());
}
int main()
{
A a;
auto lambda = [a]() -> int {
return a.value;
};
function(lambda);
return 0;
}
Output is this:
A
copy A
copy A
copy A
100
~A
~A
~A
~A
And my question is why struct A is copied 3 times, not 2?
One copy takes lambda capture, second takes passing argument to function and third takes what?
You will see the same number of copy operations, if you change your code as follows:
int main()
{
A a;
auto&& lambda = [a]() -> int {
return a.value;
};
std::function<int()>{lambda};
}
The first copy/move construction occurs when creating the lambda. The second and third copy/move constructions happen during construction of the std::function. According to N3690, the used constructor of std::function looks as follows:
template <class F> function(F);
That means, the passed argument will be copied/moved once when passing the argument to the constructor. Within the constructor, it will be copied/moved another time for type erasure.
If the constructor would use references instead (e.g. with perfect forwarding), you would only see two copy/move constructions. However, I don't know why it wasn't used in this case.
template <typename Arg> function(Arg&&);

Resources