Realmente quiero que uses std::get
como el funtor, porque ya está previsto como una función de la biblioteca !!
¿No sería genial si pudiéramos escribir esta línea?
std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
... Pero es un poco más terrible que eso. Es necesario para eliminar la ambigüedad, que get
de usar:
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;
}
El problema es, std::get
is overloaded a tomar 1. pair&
, 2. const pair&
, y 3. pair&&
como los parámetros, por lo que funcionará para cualquier tipo de pareja como entrada.Por desgracia, las sobrecargas en el camino de la deducción tipo de plantilla para std::transform
, por lo que nuestra línea original
std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
rendimientos
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>);
No sé a qué sobrecarga de std::get
está solicitando al deducir la plantilla para std::transform
, por lo que debe especificarla manualmente. Al colocar el puntero de función en el tipo correcto, se le dice al compilador: "¡Oye, usa la sobrecarga, donde get
toma const&
y devuelve const&
!"
Pero al menos estamos usando componentes de biblioteca estándar (yay)?
Y en cuanto a número de líneas, no es peor que las otras opciones: http://ideone.com/6dfzxz
¿Alguien puede pensar en alguna mejora? Sería genial poder usar 'std :: get' de esta manera. ... Realmente debería estar usando 'reinterperet_cast &)> (std :: get <0>)', pero eso parece incluso peor ... –
NHDaly
Creo que es posible reemplazar el elenco "duro" con la función get envuelta dentro de una lambda para la cual se pueden especificar los argumentos –