没有 bool 数组的类模板特化?

nya*_*108 27 c++ stdvector template-specialization class-template stdarray

根据https://en.cppreference.com/std::vector<bool>具有类模板专业化,而std::array<bool, N>没有。不提供的原因有哪些?

Mar*_*k R 24

std::vector被引入时,专业化bool被认为是一个好主意。基本上在那个时候,普通电脑有4MB的内存,所以节省电脑内存是相当重要的。现在我们只说“内存很便宜”(引用鲍勃叔叔的话)。

后来事实证明,这种专业化造成的问题多于其价值。

问题在于,与常规的老式 C-array 相比,这种向量的元素之一的地址是一个复杂的对象(它必须存储关于哪个位保存哪个值的信息)bool a[]

由于必须保留兼容性,因此不能放弃此专业化,但根据该课程,相同的方法并未应用于std::array.

另一个原因是它std::array应该是一个C数组包装器,所以它必须尽可能相似bool a[N],并且在使用时必须产生相同的机器代码。

最后一件事,正如 Cody Gray 在有问题的评论中指出的那样,std::bitset是一个恒定大小的位数组,因此此类功能已经可用(并且可以在需要时使用)。


for*_*818 13

这是一个关于 C++ 进化史的问题。事后看来,一个可能的解释是:

std::vector<bool>是一个错误。astd::vector<bool>与 非常不同,这是一个主要的烦恼std::vector<T>。与vectors一起使用的通用代码通常需要std::vector<bool>. 用户通常不得不应用奇怪的解决方法,例如使用std::vector<char>代替std::vector<bool>. 现在我们不能在不破坏大量现有代码的情况下返回。以我们现在所知道的,也许std::vector<bool>永远不会把它变成 C++。

std::array仅在 C++11 中添加。没有理由再犯同样的错误。


Pic*_*ent 9

最初的动机,专门std::vectorbool是优化内存使用情况。

然而,这是一个坏主意,因为这种专业化的行为与平时不同std::vector(请参见下面的示例)。

这个错误后来没有用 C++11 重现 std::array

#include <array>
#include <vector>

int main()
{
  std::vector<int> i_v(4);
  int i_a = *&i_v[3]; // ok

  std::vector<bool> v(4);
  bool a = *&v[3]; // Compile-time error

  std::array<bool,4> w;
  bool b = *&w[3]; // ok
}
Run Code Online (Sandbox Code Playgroud)


dfr*_*fri 7

std::vector<bool>专业化引入早在1994年,作为每lib.vector.boolWG21 / N0545 (1) [重点矿]:

23.1.6 类vector<bool>[lib.vector.bool]

为了优化空间分配,提供了一个专业化bool:[...]

出于优化空间分配的动机,这是当时稀少的资源。

回想起来,结果证明这是一个非常糟糕的主意,随着计算机硬件可用空间的快速增长,最初的动机变得毫无意义。

std::array另一方面,在 C++11 中引入了很久之后,例如auto类型推导,一种突出了特化的另一个问题的机制std::vector<bool>。自然,库规范编写者std::vector<bool>在设计时不会重复同样的错误std::array

例如,以下代码段

#include <type_traits>
#include <vector>

int main() {
    std::vector<bool> v{false, false, true, true};
    auto bool_value = v[1];
    static_assert(std::is_same_v<decltype(bool_value), bool>, "");  // Error!
}   
Run Code Online (Sandbox Code Playgroud)

失败,错误消息bool_value不是 type bool,而是神秘类型(实现定义)

error: static_assert failed due to requirement
'std::is_same_v<
    std::__1::__bit_reference<
        std::__1::vector<bool, std::__1::allocator<bool>>, true>, 
    bool>' ""
Run Code Online (Sandbox Code Playgroud)

(1)信息系统国际标准草案的工作文件——编程语言 C++。