【问题标题】:compiler error when pointing to an element of std::vector<bool>?指向 std::vector<bool> 的元素时出现编译器错误?
【发布时间】:2017-04-18 03:46:43
【问题描述】:

尝试使用std::vector&lt;bool&gt; 我遇到了一个令我非常惊讶的编译器错误。

简而言之,获取std::vector&lt;unsigned char&gt; 元素的地址并将其分配给unsigned char 指针:

std::vector<unsigned char> test(10);
unsigned char *pb = &test[0];

运行良好,但尝试使用 std::vector&lt;bool&gt; 执行相同操作会导致编译器错误:

int main() {

    std::vector<bool> test(10);
    bool *pb = &test[0];    // line 4, compile error

    return 0;
}

在 Visual Studio 上,它是这样说的:

std::vector bool cannot convert std::_Vb_reference<_Alloc> * to bool *

虽然键盘 (see example at http://codepad.org/vaiN3iEq) 说:

cc1plus: warnings being treated as errors
In function 'int main()':
Line 4: warning: taking address of temporary
Line 4: error: cannot convert '__gnu_norm::_Bit_reference*' to 'bool*' in initialization
compilation terminated due to -Wfatal-errors.

我认为 boolunsigned char 在内部是相同的(只是一个 1 字节类型,有一些编译器的东西强制 bool 只允许真/假值)。但我没想到会出现这样的问题!知道为什么吗?!

请注意,我知道位集,但对在这里使用它们不感兴趣。

【问题讨论】:

  • 另一方面,我更喜欢使用迭代器而不是运算符的地址。使用迭代器可以提供更好的可扩展设计。
  • @YogeshSajanikar 这在这里很不合时宜,但我首先看到迭代器是不可读的(在 for (int i=0; i&lt;10; i++) a[i]=0;for (std::vector&lt;my_type&gt;::iterator it=a.begin(); it!=a.end(); ++it) *it=0 之间,第一个是 much 更具可读性) 并且我猜它们会导致性能下降(尤其是在使用所有不同检查等进行调试时),这对于像在内存中的给定位置放置/访问值这样简单的事情来说是一种痛苦。它们可能对其他包含(std::map 等)有用,但对于 std::vectors,我只是讨厌它们。 ;)

标签: c++ vector


【解决方案1】:

是的,boolunsigned char 通常各自占用相同数量的内存,但这并不能使 vector&lt;bool&gt;vector&lt;unsigned char&gt; 相同!

vector&lt;bool&gt; 被标准给予了非常、非常 的特殊处理,以便尽可能地将元素打包(1990 年代的人认为这很聪明,因为 bool 有一个只有两种状态),结果就是你所看到的:它的元素是不可寻址的。

避免!

【讨论】:

  • 谢谢!我并不是说向量是相同的,我仍然可以做 double* v = (double*) my_unsigned_char_vector[0] 并且可以编译。 “尽可能靠近包装元素”是什么意思?这些不是位集,排列一系列 8 位变量的最接近的方法是将它们连续放置......
  • @WhitAngl 标准要求vector&lt;bool&gt; 是一个位集。所以它的operator[] 返回一个代理对象(因为您可以返回对位字段的引用)。而且你不能在你的表达式中使用那个代理的地址,因为它是一个右值。
  • @WhitAngle vector&lt;bool&gt; 是一种专门设计,旨在允许将位打包在一起。也就是说,它可能在内部存储 8 位 chars 并将每个位用作 bool
  • @WhitAngl:你为什么断言“这些不是位集”?
  • @LightnessRacesinOrbit 我是这么认为的,但显然是错误的。我认为 std::vector 只是一个简单的元素数组,所有其他类型似乎都是如此。
猜你喜欢
  • 2015-01-04
  • 2016-04-30
  • 2011-03-18
  • 1970-01-01
  • 1970-01-01
  • 2020-01-10
  • 1970-01-01
  • 1970-01-01
  • 2014-10-22
相关资源
最近更新 更多