I have a vector of integers and I want to convert it to a vector of pairs (pair consists of a bool and a int). My current code is simple like this:
std::vector<int> a;
std::vector<std::pair<bool,int> > b;
a.push_back(1);
a.push_back(2);
a.push_back(3);
for(int i = 0; i < a.size(); ++i)
{
b.push_back(std::make_pair(false, a[i]));
}
Is there any way to do this without writing the loop myself? Probably using some algorithms?
The transform() function in C++ sequentially applies an operation to the elements of an array(s) and then stores the result in another output array. The transform function is used in two forms: Unary operation: The operation is applied to each element in the input range, and the result is stored in the output array.
std::transform applies the given function to a range and stores the result in another range, keeping the original elements order and beginning at d_first. 1) The unary operation unary_op is applied to the range defined by [first1, last1) .
1. You could make a functor and std::for_each
:
struct F {
F(std::vector<std::pair<bool,int> > &b) : m_b(b){
}
void operator()(int x) {
m_b.push_back(std::make_pair(false, x));
}
std::vector<std::pair<bool,int> > &m_b;
};
std::for_each(a.begin(), a.end(), F(b));
Though this may prove to be more trouble than it's worth. But at least it would be reusable :).
Maybe there is something that could be done with boost::bind
.
2. EDIT: I was thinking you might be able to use bind with a back inserter and transform. something like this:
std::transform(a.begin(), a.end(), std::back_inserter(b), boost::bind(std::make_pair<bool, int>, false, _1));
I tried this with std::bind1st
, i thought it should have worked, but i could only get it to succeed with boost::bind
. I'll keep trying...
3. EDIT: here's a non-boost solution:
std::transform(a.begin(), a.end(), std::back_inserter(b), std::bind1st(std::ptr_fun(std::make_pair<bool, int>), false));
4. EDIT: here's a C++11 solution (which is my current favorite):
std::for_each(begin(a), end(a), [&b](int v) {
b.emplace_back(false, v);
});
or even simpler:
for(int v : a) {
b.emplace_back(false, v);
}
Nothing fancy. Just a two line solution which I like:
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> a{1,2,3,4,15};
std::vector<std::pair<bool, int>> b;
auto it = a.begin();
std::generate_n(std::back_inserter(b), a.size(), [&it]() { return std::make_pair(false, *it++); });
for(auto c : b) {
std::cout << std::boolalpha << c.first << " " << c.second << "\n";
}
}
Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With