在下面的回答中,@Incomputable基本上让我胆敢实现std::minmax_element的泛化。
您是否考虑过创建一个搜索函数,该函数基于N个谓词查找N个元素,并与迭代器返回一个std::array以找到元素?我只是相信std::minmax_element是可以推广的。
我很乐意这样做:
#include <array>
template<typename IteT, typename... PredsT>
auto multi_search_elements(IteT begin, IteT end, PredsT const&... preds) {
const std::size_t count = sizeof...(PredsT);
std::array<IteT, count> selected;
selected.fill(begin);
if(begin != end) {
for(++begin; begin != end; ++begin) {
std::size_t i = 0;
( (selected[i] = preds(*selected[i], *begin) ? selected[i] : begin,
++i), ...);
}
}
return selected;
}用法:
#include <iostream>
#include <vector>
#include <functional>
int main() {
std::vector<int> vals = {1,2,3,4,5};
auto found = multi_search_elements(vals.begin(), vals.end(), std::less<int>(), std::greater<int>());
for(auto i : found) {
std::cout << *i << std::endl;
}
return 0;
}编辑:我理解对于那些不习惯这类代码的人来说,这个折叠表达式可能看起来像伏都教,所以对于那些好奇的人,我将详细说明这里发生了什么:
折叠表达式如下所示:(EXPR, ...),它将扩展到EXPR, EXPR, EXPR, etc...,其中所使用的“二进制”运算符实际上是逗号运算符,它实际上只是对表达式进行排序,而使它们不相关。
在此之后,我所做的就是让EXPR成为SUB_EXPR, ++i,所以整个事情扩展为:
(SUB_EXPR, ++i), (SUB_EXPR, ++i), (SUB_EXPR, ++i), (SUB_EXPR, ++i), ...其实质是:
selected[i] = preds_0(*selected[i], *begin) ? selected[i] : begin,
++i,
selected[i] = preds_1(*selected[i], *begin) ? selected[i] : begin,
++i,
selected[i] = preds_2(*selected[i], *begin) ? selected[i] : begin,
++i,
selected[i] = preds_3(*selected[i], *begin) ? selected[i] : begin,
++i发布于 2017-11-21 10:03:37
这段代码非常好,而且没有什么需要改进的地方。两行折叠表达式确实受益于描述中的解释性注释,所以它也许可以在代码中得到一个摘要?
我发现了一些很小的简化:
count为静态const =sizeof.(PredsT);++begin循环中复制for不同,我们可以转换为一个更简单的while循环: we (++begin != end) {selected不同,我们可以选择迭代(并避免不执行赋值,并避免需要记住逗号操作符的优先级):auto p= selected.begin();(preds(**p,*begin)?*p++:*p++ = begin),.;https://codereview.stackexchange.com/questions/180925
复制相似问题