【问题标题】:std::vector<bool> with only one true elementstd::vector<bool> 只有一个真元素
【发布时间】:2013-07-26 11:24:49
【问题描述】:

我需要一个std::vector&lt;bool&gt;,其中只有一个元素在程序后面可能为真。 我的尝试是(在 for 循环中)

BOOST_FOREACH( bool b, boolvector)
{
    b = false;
}
boolvector[j] = true;

但是当它执行时,在执行 BOOST_FOREACH 时元素不会重置为 false(boost 库的函数可以更方便地通过容器进行迭代(请参阅boost documentation)。

P.S.:我知道 std::vector 是个坏东西,但应该足够了。

【问题讨论】:

  • I know that std::vector is a broken thing 是这样吗?
  • @Nbr44 std::vector&lt;bool&gt; 不是 std::vector&lt;T&gt;T=bool 的实例化。这是一种特殊化,每个bool 只占用1 位。这意味着它不会为您提供对包含的bools 的引用,而是为您提供代理对象。基本上它的行为方式与std::vector 的其他实例不同,这被广泛认为是一个错误。从设计的角度来看“破碎”,而不是技术角度。
  • 它看起来像一个函数声明,其中 bool b 是按值调用的,而不是引用
  • 我认为您可以改用std::bitset(或boost::dynamic_bitset)。你试过了吗?
  • 我建议将向量替换为真正元素的索引。

标签: c++ boost vector foreach boolean


【解决方案1】:

我会在几分钟后试试这个,但我怀疑你想要

BOOST_FOREACH(std::vector<bool>::reference b, boolvector)
{
    b = false;
}

std::vector&lt;bool&gt;,正如你所说,是“损坏”的,取消引用迭代器并没有给你一个很好的方便引用,它给你一些代理对象:http://en.cppreference.com/w/cpp/container/vector_bool

编辑:是的,这行得通:

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <vector>

#include <boost/foreach.hpp>

void print (const std::vector<bool>& bv)
{
    std::cout << std::boolalpha;
    for (auto it = std::begin(bv); it != std::end(bv); ++it)
        std::cout << *it << ' ';
    std::cout << '\n';
}


int main()
{
    std::vector<bool> boolvector {true, false, true, false};
    print(boolvector);

    BOOST_FOREACH(std::vector<bool>::reference b, boolvector)
    {
        b = false;
    }

    print(boolvector);
}

打印:

$ ./a.out 
true false true false 
false false false false 

这个:

BOOST_FOREACH(auto b, boolvector)

也可以,但是

BOOST_FOREACH(auto& b, boolvector)

没有(由于非const 临时引用而无法编译)。

但是,正如 Nawaz 指出的那样,如果您支持 c++11,只需完全放弃 BOOST_FOREACH,然后写:

for (auto b : boolvector)

稍后编辑:

我不知道我是怎么错过这个的,但看起来正确的解决方案是使用assign

b.assign(b.size(), false);
b[i] = true;

【讨论】:

  • 是的,我看到了我现在犯的错误。但是不是也不能得到一个bit的引用吗?
  • @BoBTFish:是的,你是对的。 auto bdoes work.
  • 顺便说一句,如果你使用auto,那为什么还要使用BOOST_FOREACH?您可以使用基于范围的for。 ;-) +1
  • @Nawaz 没错。我假设实际代码中没有 c++11,因此首先使用BOOST_FOREACH。为了方便起见,我在示例中使用了它,并提到了 auto,因为 cmets 在一个现已删除的答案中。
猜你喜欢
  • 2016-03-31
  • 2016-10-16
  • 1970-01-01
  • 2019-07-30
  • 2011-12-27
  • 1970-01-01
  • 2014-03-15
  • 1970-01-01
  • 2012-08-14
相关资源
最近更新 更多