Я играл с C++ 17/C++ 1Z особенности apply
и invoke
немного В конце концов я хотел использовать apply
в результате equal_range
непосредственно , как это:Как сделать std :: distance a Callable для применения или вызова?
cout << apply(std::distance, data.equal_range(4)) << '\n';
Это не компилировать. Я думал, что это потому, что equal_range
вернул pair
, а не tuple
, но, как оказалось, это не тот случай.
Мой более крупный пример компилирует все, если я использую Lambda вместо std::distance
. Когда я думаю о причине этого, я предполагаю, что он имеет какое-то отношение к созданию шаблона функции distance
. Хмм, жаль, что это не работает без него, потому что я с трудом его создание экземпляра `станд :: расстояние :: итератор>
#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';
}
Есть ли лучше, более компактный способ использовать apply
и invoke
с функциями шаблона, такими как distance
без явного создания экземпляра или лямбда?
'distance' - это шаблон функции, а не функция шаблона, что является проблемой. ('distance :: iterator>' будет примером функции шаблона.) –
ildjarn
@ildjarn Я понимаю, что вы имеете в виду, я должен получить свою терминологию прямо. Хорошо, я знаю, что такое * function template *, но что такое * функция шаблона *, а если не просто * функция *? 'std :: distance' является FT, почему' расстояние :: iterator> 'a TF, а не только F? Потому что он создается из FT? Если да, существует ли разница между TF и F? –
towi
"* то, что является функцией шаблона, то, если не просто функция *" Это действительно просто функция, но она имеет меньшее значение в разрешении перегрузки, чем "регулярная" функция, и поэтому стоит различать. (В этом случае нет набора перегрузки, состоящего из обеих функций и функций шаблона, поэтому он здесь не применяется.) – ildjarn