How to skip the first element of the vector and iterate from second using range based for loops [duplicate] - c++11

I have a std::vector<std::string> v; (initialized). How can I use the range-for loop for accessing all elements except the first one (on index zero). For all elements:
for (const string & s: v)
process(s);
Instead of the v a range expression can be used. How can I write the range expression to skip the first element (or skip the first n elements)?
I know how to get the effect using v.begin() + 1 and using the classic loop. I am searching for the new, more readable, recommended alternative to do that. Possibly something similar to Python slicing? ...like:
for s in v[1:]:
process(s)

Until ranges make it into the standard library, you won't get any better than a vanilla for loop in plain C++ :
for(auto i = begin(v) + 1, e = end(v); i !=e; ++i)
// Do something with *i

Create a wrapper for which begin() and end() return the correct iterators and then you can use that as the second argument.
#include <iostream>
#include <vector>
template< typename Collection >
class FromNth
{
Collection& coll_;
size_t offset_;
public:
FromNth( Collection& coll, size_t offset )
: coll_( coll ), offset_( offset )
{
}
// will nicely resolve to const_iterator if necessary
auto begin() const -> decltype( coll_.begin() )
{ return coll_.begin() + offset_; }
auto end() const -> decltype( coll_.end() )
{ return coll_.end(); }
};
template< typename Collection >
FromNth<Collection> makeFromNth( Collection& collection, size_t offset )
{
return FromNth<Collection>( collection, offset );
}
template< typename Collection >
auto begin( const FromNth<Collection> & wrapper ) -> decltype( wrapper.begin() )
{
return wrapper.begin();
}
template< typename Collection >
auto end( const FromNth<Collection> & wrapper ) -> decltype( wrapper.end() )
{
return wrapper.end();
}
int main()
{
std::vector< int > coll { 2, 3, 5, 7, 11, 13, 17, 19, 23 };
for( auto x : makeFromNth( coll, 1 ) )
{
std::cout << x << '\n';
}
return 0;
}
Note that my fromNth "begin" is undefined behaviour if the size of the input is less than the offset. (If it's equal then it's well defined and begin == end). Therefore do a size check first.
Note: if you are using a recent enough version of boost then iterator_range may already provide you such a "collection" that is similar to my "FromNth".
for( auto const& s : boost::make_iterator_range( v.begin() + 1, v.end() ) )
{
process( s );
}
Note: the code above worked on CodingGround using C++11 GNU 4.8.3. (That site is very slow though). From C++14 you will not need the ->decltype statements (which are needed in C++11 for templates).
Output:
sh-4.3$ g++ -std=c++11 -o main *.cpp
sh-4.3$ main
3
5
7
11
13
17
19
23

Related

bad_function_call when using lambda function on boost:heap

I want to create a heap data structure to be able to update the value .
but my simple code below throw an exception. why it gives the following:
109 : 3 terminate called after throwing an instance of 'std::bad_function_call' what(): bad_function_call
#include <set>
#include <algorithm>
#include <functional>
#include <boost/heap/fibonacci_heap.hpp>
int main() {
// Creating & Initializing a map of String & Ints
std::map<int, vector<int> > mapOfWordCount = { { 1000, {0,1,10,8} }, { 10001, {1,5,99} }, { 1008, {7,4,1} } , { 109, {1,5,3} }};
// Declaring the type of Predicate that accepts 2 pairs and return a bool
typedef std::function<bool(std::pair<int, vector<int> > v1, std::pair<int, vector<int> > v2)> Comparator;
// Defining a lambda function to compare two pairs. It will compare two pairs using second field
Comparator compFunctor =
[](std::pair<int, vector<int> > elem1 ,std::pair<int, vector<int> > elem2)
{
return elem1.second.size() > elem2.second.size();
};
boost::heap::fibonacci_heap <std::pair<int, vector<int> >, boost::heap::compare<Comparator> > pq;
typedef boost::heap::fibonacci_heap< std::pair<int, vector<int> >, boost::heap::compare<Comparator> >::handle_type handle_t;
handle_t* tab_handle = new handle_t [mapOfWordCount.size()];
unsigned iter(0);
for( auto& element : mapOfWordCount) {
tab_handle[iter++]=pq.push(element);
std::cout << element.first << " : " << element.second.size() << std::endl;
}
}
std::bad_function_call exception is caused (in this case) when calling a std::function that is empty.
I have made this work by making Comparator a functor.
struct Comparator
{
bool operator()(std::pair<int, std::vector<int> > elem1, std::pair<int, std::vector<int> > elem2) const
{
return elem1.second.size() > elem2.second.size();
}
};
This can then be used in the declarations of pq and handle_t.
Output:
109 : 3
1000 : 4
1008 : 3
10001 : 3
See demo here.
You can figure out how to make it work with a lambda.
Hint: It involves using the lambda compFunctor as an argument for construction.

derivation of return type based on max range of input possible in C++

I was recently asked this question in an interview of C++ where I
was asked to improve the below piece of code which fails when
adding two int's results in the result being long and return
type needs accordingly to be derived.
Here the below code fails because the decltype() based derivation is not intelligent enough to identify based on the actual range of values of input but the type and derives return type as same. Hence we need perhaps some metaprogramming template technique to derive the return type as long if T is int.
How can this be generalized any hints or clues?
I feel that decltype() won't be helpful here.
#include<iostream>
#include<string>
#include<climits>
using namespace std;
template<typename T> auto adder(const T& i1, const T& i2) -> decltype(i1+i2)
{
return(i1+i2);
}
int main(int argc, char* argv[])
{
cout << adder(INT_MAX-10, INT_MAX-3) << endl; // wrong.
cout << adder<long>(INT_MAX-10, INT_MAX-3) << endl; // correct!!.
return(0);
}
Hence we need perhaps some metaprogramming template technique to derive the return type as long if T is int.
Not so simple.
If T is int, you're non sure that long is enough.
The standard say only that
1) the number of bits for int (sizeof(int) * CHAR_BIT) is at least 16
2) the number of bits for long (sizeof(long) * CHAR_BIT) is at least 32
3) sizeof(int) <= sizeof(long)
So if a compiler manage a int with sizeof(int) == sizeof(long), this is perfectly legal and
adder<long>(INT_MAX-10, INT_MAX-3);
doesn't works because long can be not enough to contain (without overflow) the sum between two int's.
I don't see a simple and elegant solution.
The best that come in my mind is based on the fact that C++11 introduced the following types
1) std::int_least8_t, smallest integer type with at least 8 bits
2) std::int_least16_t, smallest integer type with at least 16 bits
3) std::int_least32_t, smallest integer type with at least 32 bits
4) std::int_least64_t, smallest integer type with at least 64 bits
C++11 also introduce std::intmax_t as the maximum width integer type.
So I propose the following template type selector
template <std::size_t N, typename = std::true_type>
struct typeFor;
/* in case std::intmax_t is bigger than 64 bits */
template <std::size_t N>
struct typeFor<N, std::integral_constant<bool,
(N > 64u) && (N <= sizeof(std::intmax_t)*CHAR_BIT)>>
{ using type = std::intmax_t; };
template <std::size_t N>
struct typeFor<N, std::integral_constant<bool, (N > 32u) && (N <= 64u)>>
{ using type = std::int_least64_t; };
template <std::size_t N>
struct typeFor<N, std::integral_constant<bool, (N > 16u) && (N <= 32u)>>
{ using type = std::int_least32_t; };
template <std::size_t N>
struct typeFor<N, std::integral_constant<bool, (N > 8u) && (N <= 16u)>>
{ using type = std::int_least16_t; };
template <std::size_t N>
struct typeFor<N, std::integral_constant<bool, (N <= 8u)>>
{ using type = std::int_least8_t; };
that, given a number of bits, define the corresponding smallest "at least" integer type.
I propose also the following using
template <typename T>
using typeNext = typename typeFor<1u+sizeof(T)*CHAR_BIT>::type;
that, given a type T, detect the smallest integer type that surely contain a sum between two T values (a integer with a number of bits that is at least the number of bits of T plus one).
So your adder() simply become
template<typename T>
typeNext<T> adder (T const & i1, T const & i2)
{ return {typeNext<T>{i1} + i2}; }
Observe that th returned value isn't simply
return i1 + i2;
otherwise you return the correct type but with the wrong value: i1 + i2 is calculated as a T value so you can have overflow, then the sum is assigned to a typeNext<T> variable.
To avoid this problem, you have to initialize a typeNext<T> temporary variable with one of two values (typeNext<T>{i1}), then add the other (typeNext<T>{i1} + i2) obtaining a typeNext<T> value, finally return the computed value. This way the sum in calculated as a typeNext<T> sum and you doesn't have overflow.
The following is a full compiling example
#include <cstdint>
#include <climits>
#include <iostream>
#include <type_traits>
template <std::size_t N, typename = std::true_type>
struct typeFor;
/* in case std::intmax_t is bigger than 64 bits */
template <std::size_t N>
struct typeFor<N, std::integral_constant<bool,
(N > 64u) && (N <= sizeof(std::intmax_t)*CHAR_BIT)>>
{ using type = std::intmax_t; };
template <std::size_t N>
struct typeFor<N, std::integral_constant<bool, (N > 32u) && (N <= 64u)>>
{ using type = std::int_least64_t; };
template <std::size_t N>
struct typeFor<N, std::integral_constant<bool, (N > 16u) && (N <= 32u)>>
{ using type = std::int_least32_t; };
template <std::size_t N>
struct typeFor<N, std::integral_constant<bool, (N > 8u) && (N <= 16u)>>
{ using type = std::int_least16_t; };
template <std::size_t N>
struct typeFor<N, std::integral_constant<bool, (N <= 8u)>>
{ using type = std::int_least8_t; };
template <typename T>
using typeNext = typename typeFor<1u+sizeof(T)*CHAR_BIT>::type;
template<typename T>
typeNext<T> adder (T const & i1, T const & i2)
{ return {typeNext<T>{i1} + i2}; }
int main()
{
auto x = adder(INT_MAX-10, INT_MAX-3);
std::cout << "int: " << sizeof(int)*CHAR_BIT << std::endl;
std::cout << "long: " << sizeof(long)*CHAR_BIT << std::endl;
std::cout << "x: " << sizeof(x)*CHAR_BIT << std::endl;
std::cout << std::is_same<long, decltype(x)>::value << std::endl;
}
In my Linux 64bit platform, i get 32bit for int, 64bit for long and for x and also that long and decltype(x) are the same type.
But this is true for my platform; nothing guaranties that long and decltype(x) are ever the same.
Observe also that trying to get a type for the sum of two std::intmax_t's
std::intmax_t y {};
auto z = adder(y, y);
gives an error and doesn't compile because isn't defined a typeFor for a N bigger that sizeof(std::intmax_t)*CHAR_BIT.

Variadic Template Recursion

I am trying to use recursion to solve this problem where if i call
decimal<0,0,1>();
i should get the decimal number (4 in this case).
I am trying to use recursion with variadic templates but cannot get it to work.
Here's my code;
template<>
int decimal(){
return 0;
}
template<bool a,bool...pack>
int decimal(){
cout<<a<<"called"<<endl;
return a*2 + decimal<pack...>();
};
int main(int argc, char *argv[]){
cout<<decimal<0,0,1>()<<endl;
return 0;
}
What would be the best way to solve this?
template<typename = void>
int decimal(){
return 0;
}
template<bool a,bool...pack>
int decimal(){
cout<<a<<"called"<<endl;
return a + 2*decimal<pack...>();
};
The problem was with the recursive case, where it expects to be able to call decltype<>(). That is what I have defined in the first overload above. You can essentially ignore the typename=void, the is just necessary to allow the first one to compile.
A possible solution can be the use of a constexpr function (so you can use it's values it's value run-time, when appropriate) where the values are argument of the function.
Something like
#include <iostream>
constexpr int decimal ()
{ return 0; }
template <typename T, typename ... packT>
constexpr int decimal (T const & a, packT ... pack)
{ return a*2 + decimal(pack...); }
int main(int argc, char *argv[])
{
constexpr int val { decimal(0, 0, 1) };
static_assert( val == 2, "!");
std::cout << val << std::endl;
return 0;
}
But I obtain 2, not 4.
Are you sure that your code should return 4?
-- EDIT --
As pointed by aschepler, my example decimal() template function return "eturns twice the sum of its arguments, which is not" what do you want.
Well, with 0, 1, true and false you obtain the same; with other number, you obtain different results.
But you can modify decimal() as follows
template <typename ... packT>
constexpr int decimal (bool a, packT ... pack)
{ return a*2 + decimal(pack...); }
to avoid this problem.
This is a C++14 solution. It is mostly C++11, except for std::integral_sequence nad std::index_sequence, both of which are relatively easy to implement in C++11.
template<bool...bs>
using bools = std::integer_sequence<bool, bs...>;
template<std::uint64_t x>
using uint64 = std::integral_constant< std::uint64_t, x >;
template<std::size_t N>
constexpr uint64< ((std::uint64_t)1) << (std::uint64_t)N > bit{};
template<std::uint64_t... xs>
struct or_bits : uint64<0> {};
template<std::int64_t x0, std::int64_t... xs>
struct or_bits<x0, xs...> : uint64<x0 | or_bits<xs...>{} > {};
template<bool...bs, std::size_t...Is>
constexpr
uint64<
or_bits<
uint64<
bs?bit<Is>:std::uint64_t(0)
>{}...
>{}
>
from_binary( bools<bs...> bits, std::index_sequence<Is...> ) {
(void)bits; // suppress warning
return {};
}
template<bool...bs>
constexpr
auto from_binary( bools<bs...> bits={} )
-> decltype( from_binary( bits, std::make_index_sequence<sizeof...(bs)>{} ) )
{ return {}; }
It generates the resulting value as a type with a constexpr conversion to scalar. This is slightly more powerful than a constexpr function in its "compile-time-ness".
It assumes that the first bit is the most significant bit in the list.
You can use from_binary<1,0,1>() or from_binary( bools<1,0,1>{} ).
Live example.
This particular style of type-based programming results in code that does all of its work in its signature. The bodies consist of return {};.

using range based for loop for iterating on a sub range

Is it possible to loop over sub range using range based for loop ?
std::vector <std::string> inputs={"1","abaaaa","abc","cda"};
for (auto &it : new_vector(inputs.begin()+1, inputs.end()))
{
// …
}
You could use Boost's iterator_range:
for (auto &it : boost::make_iterator_range(inputs.begin()+1, inputs.end()))
{
cout << it << endl;
}
demo
Alternatively you could write your own wrapper.
Unfortunately, there is no such thing in the C++ standard library. However, you can define your own wrapper like this (requires at least C++ 11 - which should not be problem in 2021):
template<typename Iter>
struct range
{
Iter b, e;
Iter begin() const { return b; }
Iter end() const { return e; }
};
template<typename T>
auto slice(const T& c, std::size_t from, std::size_t to = -1) -> range<decltype(c.begin())>
{
to = (to > c.size() ? c.size() : to);
return range<decltype(c.begin())>{c.begin() + from, c.begin() + to};
}
And then you can use it:
std::vector<int> items(100);
// Iterates from 4th to 49th item
for (auto x: slice(items, 4, 50))
{
}
// Iterates from 15th to the last item
for (auto x: slice(items, 15))
{
}
tl;dr
Long story short, you #include <range/v3/view/subrange.hpp> and change your new_vector to ranges::subrange. And that's it. Demo on Compiler Explorer.
So
Given the name you imagine for this function, new_vector, maybe you think you need the entity on the right of : to be a std::vector or at least some type of container.
If that's the case, then change your mind, it's not needed. All that : wants from its "right hand side" is that it have begin and end defined on them, member or non member. For instance, this compiles and runs just fine:
struct A {};
int* begin(A);
int* end(A);
struct B {
int* begin();
int* end();
};
int main()
{
for (auto it : A{}) {}
for (auto it : B{}) {}
}

Find an element of vector which is presented in the map

I need to find an element of vector which is presented in map. Hard part is that vector consists of structures, so you should call member function to extract value form the structure first to compare it to the map elements.
So, with for cycle it's pretty easy:
vector<A>::iterator it;
for( it = vec.begin(); it != vec.end(); ++it )
{
if( mp.count( it->getKey() ) )
{
break;
}
}
My question: is there any way to do it in one line, something like
//this doesn't work as count accepts key_type
vector<A>::iterator it = find_if( vec.begin(), vec.end(), boost::bind( &map<string, string>::count, mp, boost::bind( &A::getKey, _1 ) )) != 0);
Full example, to test
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/assign.hpp>
using namespace std;
class A{
public:
A( const std::string& key )
: key( key ) {}
std::string getKey(){ return key; }
private:
std::string key;
};
int main(int argc, const char *argv[]) {
map<string, string> mp = boost::assign::map_list_of( "Key1", "Val1" ) ( "Key2", "Val2" ) ( "Key3", "Val3" );
vector<A> vec = boost::assign::list_of( "AAA" ) ( "Key2" ) ( "BBB" );
// vector<A>::iterator it = find_if( vec.begin(), vec.end(), boost::bind( &map<string, string>::count, mp, boost::bind( &A::getKey, _1 ) )) != 0);
vector<A>::iterator it;
for( it = vec.begin(); it != vec.end(); ++it )
{
if( mp.count( it->getKey() ) )
{
break;
}
}
cout << ( it != vec.end() ? "found" : "not found" ) << endl;
return 0;
}
Thanks in advance
Your solution was close, there is just one closing parenthesis too many. Placing each parenthesis on a newline with indenting for each level emphasizes the invalid parenthesis:
vector<A>::iterator it = find_if
(
vec.begin(), vec.end(), boost::bind
(
&map<string, string>::count, &mp, boost::bind
(
&A::getKey, _1
)
)
) // one too many
!= 0);
In its simplest form, the line becomes iterator = find_if(...) != 0), which will cause the compiler to fail on either:
Not being able to find operator!=(iterator, int).
The ) token in != 0).
With correct parentheses, != 0 uses an operator overload provided by boost::bind. The line would look like:
vector<A>::iterator it = find_if(vec.begin(), vec.end(),
boost::bind(&map<string, string>::count, &mp,
boost::bind(&A::getKey, _1)) != 0);
However, consider the readability of such a simple operation. If a simple for loop is not generic and reusable enough, then consider hiding it within a convenience function:
template <typename InputIterator,
typename C,
typename Fn>
InputIterator find_if_contains(
InputIterator first,
InputIterator last,
const C& container,
Fn fn)
{
while (first != last)
{
if (0 != container.count(fn(*first))) return first;
++first;
}
return last;
}
...
vector<A>::iterator it = find_if_contains(
vec.begin(), vec.end(),
mp, boost::bind(&A::getKey, _1)
);
Otherwise, a custom predicate type may enhance readability while providing some extra flexibility for reuse with different types. For example, consider the following predicate type that works for various types of associative containers:
template <typename C,
typename Fn>
struct contains_predicate
{
contains_predicate(const C& container, Fn fn)
: container_(&container), fn_(fn)
{}
template <typename T>
bool operator()(T& t)
{
return 0 != container_->count(fn_(t));
}
const C* container_;
Fn fn_;
};
template <typename C,
typename Fn>
contains_predicate<C, Fn>
contains(const C& container, Fn fn)
{
return contains_predicate<C, Fn>(container, fn);
}
...
vector<A>::iterator it = find_if(vec.begin(), vec.end(),
contains(mp, boost::bind(&A::getKey, _1)));
In C++11, use a lambda:
find_if(vec.begin(), vec.end(), [&](A const & a){return mp.count(a.getKey());});
But since you're using Boost.Assign rather than uniform initialisation, perhaps you can't do that. I'm afraid I don't know how to construct a functor like that using bind alone.

Resources