naprawdę chcę do korzystania std::get
jako funktora, bo to już przewidziane jako funkcja biblioteki !!
Czy nie byłoby wspaniale, gdybyśmy mogli napisać tę linię?
std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
... Ale to trochę bardziej przerażające. Trzeba disambiguate która get
używać:
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;
}
Problemem jest std::get
is overloaded wziąć 1. pair&
2. const pair&
i 3. pair&&
jako parametry, tak, że będzie pracować dla jakiejkolwiek pary jako wejście.Niestety, przeciążenia uzyskać w drodze potrącenia typu szablon dla std::transform
, więc nasz oryginalnej linii
std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
plony
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>);
on nie wie, które przeciążenie std::get
prosicie podczas wyciągania szablon dla std::transform
, więc musisz określić go ręcznie. Przesyłanie wskaźnika funkcji do odpowiedniego typu informuje kompilator: "Hej, użyj przeciążenia, w którym get
pobiera const&
i zwraca const&
!"
Ale przynajmniej używamy standardowych komponentów biblioteki (yay)?
I pod względem liczby linii, to nie gorzej niż inne opcje: http://ideone.com/6dfzxz
Czy ktoś może pomyśleć o jakichkolwiek ulepszeniach? Byłoby wspaniale móc w prosty sposób używać 'std :: get' w ten sposób. ... Naprawdę powinienem prawdopodobnie używać 'reinterperet_cast &)> (std :: get <0>)', ale to wydaje się jeszcze gorsze ... –
NHDaly
Myślę, że to można zastąpić "twardą" obsadę funkcją get zawiniętą wewnątrz lambda, dla której można podać argumenty –