我使用了C ++ 17 / C ++ 1z功能apply
和invoke
最后,我想直接将apply
用于equal_range
的结果
像这样:
cout << apply(std::distance, data.equal_range(4)) << '\n';
那没编译。我认为这是因为equal_range
返回了pair
而不是tuple
,但事实证明并非如此。
如果我使用 Lambda 而不是std::distance
,我的大型示例会编译所有内容。在考虑其原因时,我认为它与实例化模板函数distance
有关。嗯,遗憾的是,如果没有它,这是行不通的,因为我很难用`std :: distance :: iterator&gt;
#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
这样的模板函数一起使用而没有显式实例化或lambda?
答案 0 :(得分:1)
#define OVERLOADS_OF(...)\
[](auto&&...args)->decltype(auto){\
return __VA_ARGS__( decltype(args)(args)... );\
}
现在OVERLOADS_OF(std::distance)
是一个可以传递给std::apply
的lambda。
我已经看到至少有一个提议将这个(更漂亮的语法,而不是基于宏的)放入标准中;我不知道它的状态。