【问题标题】:Why is std::min_element and company not specialized for std::vector<bool>为什么 std::min_element 和 company 不专门用于 std::vector<bool>
【发布时间】:2017-11-10 05:13:33
【问题描述】:

我有一个std::vector&lt;bool&gt; 实例(比如foo),如果所有元素都是true,我需要编写一个返回true 的函数。

我用

return *std::min_element(foo.begin(), foo.end());

实现这一点,但这让我想到:你知道最小元素是false,如果容器包含至少一个false 值。换句话说,您不需要遍历整个容器到end(),这意味着std::min_element 的特化是合适的,就像std::vector&lt;bool&gt; 的特化被认为是合适的一样。

我错过了什么吗?或者这会被视为过早的优化吗?也许一个好的编译器无论如何都会解决它。

【问题讨论】:

  • 为什么不使用内置短路功能的std::any_of?
  • @NathanOliver 如果 OP 想知道 all 元素是否为true,那么any_of 似乎不正确。 all_of 也有短路,如果谓词返回 false,它就会停止。
  • std::any_of 将谓词设置为false 大概是我需要做的。
  • @Someprogrammerdude 但是如果any_of 他们是假的,那么你知道他们并不都是真的。
  • @Someprogrammerdude 查看any_of 的代码后,您必须否定它的返回以获得正确的值。看起来all_of 在这里会更有意义,因为它会返回正确的值。

标签: c++ algorithm vector boolean specialization


【解决方案1】:

无需将std::min_element 专门用于std::vector&lt;bool&gt;。要获得您想要的功能,您只需使用std::any_of,它将在第一次出现时停止。

return !std::any_of(foo.begin(), foo.end(), [](auto e){ return e == false; });

如果我们按照Some programmer dude 的建议将其更改为std::all_of,那么您不需要否定返回值,这会给您

return std::all_of(foo.begin(), foo.end(), [](auto e){ return e; });

这样更简洁,更容易理解。

【讨论】:

  • 我想我需要返回!std::any_of...
  • @PaulLogue 正确。如果找到false,您想返回false。
  • 谢谢。最后我选择了std::all_of,[](auto i){return i;} 作为 lambda。上次我写了 i == true 之类的东西时,我的老板差点因为重言而砍掉我的头。
  • @ArturR.Czechowski 将参数保持为自动,因为我相信它会使代码更易于维护。
  • @NathanOliver 我想这是有争议的领域。如果它是更通用的功能,我会同意你的看法。但是在这里我们知道它是 bool 专业化的。那么,为什么不说清楚呢?
【解决方案2】:

建议:使用std::any_of,其中:

如果 pred 对范围 [first,last) 中的任何元素返回 true,则返回 true,否则返回 false。

表示一旦找到false就会返回。

例子:

// any_of example
#include <iostream>
#include <algorithm>    // std::any_of
#include <vector> 

int main () {
  std::vector<bool> foo = {true, true, true};

  if ( !std::any_of(foo.begin(), foo.end(), [](bool i){return i == false;}) )
      std::cout << "All elements are true\n";

  return 0;
}

输出:

All elements are true.

Live demo


由于您没有指定的,因此std::min_element 应该遍历整个向量,因为它是一种通用方法。

专业化可以按您说的做,您可以利用它提供的compare 功能。

【讨论】:

  • 使用auto 让每个人都开心
猜你喜欢
  • 2012-09-08
  • 1970-01-01
  • 2021-12-31
  • 2013-04-09
  • 1970-01-01
  • 2018-02-17
  • 2018-11-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多