首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >推广std::minmax_element

推广std::minmax_element
EN

Code Review用户
提问于 2017-11-21 03:02:21
回答 1查看 167关注 0票数 6

在下面的回答中,@Incomputable基本上让我胆敢实现std::minmax_element的泛化。

您是否考虑过创建一个搜索函数,该函数基于N个谓词查找N个元素,并与迭代器返回一个std::array以找到元素?我只是相信std::minmax_element是可以推广的。

我很乐意这样做:

代码语言:javascript
复制
#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;
}

用法:

代码语言:javascript
复制
#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,所以整个事情扩展为:

代码语言:javascript
复制
(SUB_EXPR, ++i), (SUB_EXPR, ++i), (SUB_EXPR, ++i), (SUB_EXPR, ++i), ...

其实质是:

代码语言:javascript
复制
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
EN

回答 1

Code Review用户

发布于 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),.;
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/180925

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档