Ich spielte mit C++ 17/C++ 1z Funktionen apply
und invoke
ein bisschen Letztlich wollte ich apply
das Ergebnis der equal_range
direkt wie folgt verwenden:Wie std :: distance a Callable für anwenden oder aufrufen?
cout << apply(std::distance, data.equal_range(4)) << '\n';
, das nicht kompilieren. Ich dachte, es war, weil equal_range
eine pair
und nicht eine tuple
zurückgegeben, aber wie sich herausstellt, ist das nicht der Fall.
Mein größeres Beispiel kompiliert alles, wenn ich ein Lambda anstelle vonverwende. Wenn ich über den Grund dafür nachdenke, nehme ich an, dass es etwas damit zu tun hat, die Template-Funktion distance
zu instantiieren. Hrm, schadet, dass dies nicht ohne es funktioniert, weil ich eine harte Zeit, es mit `std :: Abstand :: iterator>
#include <iostream>
#include <set>
#include <functional> // invoke
#include <experimental/tuple> // apply
using std::set; using std::cout;
using std::invoke;
using std::experimental::apply;
int main() {
set<int> data { 1,2,3,4,5,6 };
// the C++11-way, not possible in one line.
auto r = data.equal_range(4);
cout << std::distance(r.first, r.second) << '\n';
#if 0 // do not work
cout << invoke(std::distance, r.first, r.second) << '\n';
cout << apply(std::distance, r) << '\n';
cout << apply(std::distance, make_tuple(r.first, r.second)) << '\n';
cout << apply(std::distance, data.equal_range(4)) << '\n';
#endif
// explicitly instantiate distance: intolerably cumbersome
cout << apply(std::distance<set<int>::iterator>, data.equal_range(4)) << '\n';
// using a lambda: too long for a single line
auto d = [](auto b, auto e) { return std::distance(b, e); };
cout << invoke(d, r.first, r.second) << '\n';
cout << apply(d, r) << '\n';
cout << apply(d, make_tuple(r.first, r.second)) << '\n';
cout << apply(d, data.equal_range(4)) << '\n';
}
Gibt es eine schöne, kompakte Weise apply
zu verwenden Instanziieren haben würde und invoke
mit Template-Funktionen wie distance
ohne explizite Instanziierung oder Lambda?
"Abstand" ist eine Funktionsvorlage, keine Vorlagenfunktion, das ist das Problem. ('Abstand :: Iterator>' wäre ein Beispiel für eine Template-Funktion.) –
ildjarn
@ildjarn Ich sehe, was Sie meinen, ich muss meine Terminologie gerade zu bekommen. Ok, ich weiß was eine * Funktionsvorlage * ist, aber was ist eine * Template Funktion * dann, wenn nicht nur eine * Funktion *? 'std :: distance' ist ein FT, warum ist 'distance :: iterator>' ein TF und nicht nur ein F? Weil es von einer FT instanziiert wird? Wenn ja, gibt es einen Unterschied zwischen einem TF und einem F? –
towi
"* was ist eine Template-Funktion dann, wenn nicht nur eine Funktion *" Es ist in der Tat nur eine Funktion, aber es ist niedriger in Überladung Auflösung als eine "normale" Funktion und ist es daher wert zu unterscheiden. (In diesem Fall gibt es keinen Überladungssatz, der sowohl aus Funktionen als auch aus Vorlagenfunktionen besteht, also trifft dies hier nicht zu.) – ildjarn