I really want you to use std::get
as the functor, because it's already provided as a library function!!
Wouldn't it be great if we could write this line!?
std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
... But it's a bit more terrible than that. You need to disambiguate which get
to use:
int main() {
std::vector<int> items;
std::vector<std::pair<int, int>> pairs;
pairs.push_back(std::make_pair(1, 3));
pairs.push_back(std::make_pair(5, 7));
std::transform(pairs.begin(), pairs.end(), std::back_inserter(items),
(const int& (*)(const std::pair<int, int>&))std::get<0>);
return 0;
}
The problem is, std::get
is overloaded to take 1. pair&
, 2. const pair&
, and 3. pair&&
as the parameters, so that it will work for any sort of pair as input. Unfortunately, the overloads get in the way of the template type deduction for std::transform
, so our original line
std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
yields
error: no matching function for call to ‘transform(std::vector<std::pair<int, int> >::iterator, std::vector<std::pair<int, int> >::iterator, std::back_insert_iterator<std::vector<int> >, <unresolved overloaded function type>)’
std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
^
...
/usr/include/c++/4.8/bits/stl_algo.h:4915:5: note: template argument deduction/substitution failed:
note: couldn't deduce template parameter ‘_UnaryOperation’
std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
It doesn't know which overload of std::get
you are asking for when deducing the template for std::transform
, so you have to specify it manually. Casting the function pointer to the right type tells the compiler, "Hey, please use the overload where get
takes a const&
and returns a const&
!"
But at least we're using standard library components (yay)?
And in terms of number of lines, it's no worse than the other options:
http://ideone.com/6dfzxz