【问题标题】:cin to vector of boolscin 到布尔向量
【发布时间】:2013-03-25 14:31:32
【问题描述】:

我有这个代码:

#include <iostream>
#include <vector>

using namespace std;

int main(){
    vector <bool> v;
    cin >> v[0];
return 0;   
}

为什么我不能这样做?编译器不会编译它,但我在向量中有其他变量类型,它会工作得很好。这有什么问题?

【问题讨论】:

    标签: c++ vector stl boolean


    【解决方案1】:

    这是因为std::vector&lt;bool&gt; 是一种特化,根本不像一个向量。这被广泛认为是标准中的一个主要缺陷。

    为了节省内存,vector&lt;bool&gt; 将每个元素存储为单个位。但是位不能单独寻址,因此operator[] 不能返回连接到位的bool&amp; 引用。相反,它返回 vector&lt;bool&gt;::reference... 而 cin 不提供函数重载来处理这个问题。

    (juanchopanza 正确地指出你的向量没有元素零。但即使它通过resize 或其他机制实现,operator[] 不返回引用的事实仍然会妨碍。 )

    【讨论】:

    • 谢谢,这就够了。
    • 其实我觉得std::vector&lt;bool&gt;的奇怪在这种情况下不是问题。
    • @juanchopanza 为什么不呢?即使我在向量中推送一些元素,所以 v[0] 存在,我仍然会得到那个编译错误。
    • @MyUserIsThis 是什么编译器?我在 GCC 4.7.2 上没有遇到这个问题:请参阅 this demo
    • 我认为通过operator[] 分配是可以的,但是获取它返回的任何地址都行不通。
    【解决方案2】:

    在您调用v[0] 时,向量的大小为零,因此您访问的范围越界。这是未定义的行为

    此外,std::vector&lt;bool&gt; 是一个具有奇怪行为的特化,因为它不包含单独的 bool 元素。它的operator[] 返回一种代理对象,对该运算符的调用可能不会达到您的预期。应该小心使用,或者根本不使用。

    您可以通过将值读入局部变量然后将其推入向量的后面来解决该问题,如本工作示例 (similar live demo here) 所示:

    #include <vector>
    #include <iostream>
    
    int main()
    {
      std::vector<bool> v;
      std::cout << std::boolalpha;
      v.push_back(true);
      std::cout << v[0] << std::endl;
      bool b;
      cin >> b;
      v[0] = b;
      std::cout << v[0] << std::endl;
    }
    

    【讨论】:

    • 您对越界访问是正确的。但是,我认为这与问题无关。想象一下,v.resize(1) 被调用了。
    • @BenVoigt 这让我头疼!我已经成功避开std::vector&lt;bool&gt; 这么多年了,现在我不知道它在哪里坏了,在哪里不坏。
    【解决方案3】:

    这应该可行:

    #include <iomanip>
    
    ...
    
    bool a;
    cin >> boolalpha >> a;
    v.push_back(a);
    

    (除了 Ben Voigt 提到的问题之外,您当前的代码对于 bool 以外的类型是不安全的,因为当您访问 v[0] 时,您的向量是空的。)

    【讨论】:

      猜你喜欢
      • 2014-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-06
      相关资源
      最近更新 更多