簡體   English   中英

為什么libc ++的vector <bool> :: const_reference不是bool?

[英]Why is libc++'s vector<bool>::const_reference not bool?

第23.3.7節類vector<bool> [vector.bool],第1段規定:

template <class Allocator> class vector<bool, Allocator> {
public:
    // types:
    typedef bool              const_reference;
    ...

但是,當使用libc ++時,此程序無法編譯:

#include <vector>
#include <type_traits>

int
main()
{
    static_assert(std::is_same<std::vector<bool>::const_reference, bool>{}, "?");
}

此外,我注意到C ++標准在本規范中一直與C ++ 98一致。 我還注意到自從第一次引入libc ++以來,libc ++一直沒有遵循這個規范。

這種不合格的動機是什么?

這種擴展的動機,可以通過一致的程序檢測,因此是不符合的,是使vector<bool> vector<char> (const和其他)方面更像vector<char>

介紹

自1998年以來, vector<bool>被嘲笑為“不是一個容器”。 LWG 96是最早的LWG問題之一,它發起了辯論。 17年后的今天, vector<bool>基本保持不變。

本文進入關於如何的行為的一些具體的例子vector<bool>從每個其它實例不同vector ,從而損害通用代碼。 然而,同一篇論文詳細討論了如果正確實現了非常好的性能屬性vector<bool>

總結vector<bool>不是一個壞容器。 它實際上非常有用。 它的名字不好。

回到const_reference

如上所述, 這里詳細介紹了vector<bool>不足之處在於它在通用代碼中的行為與其他vector實例相比有所不同。 這是一個具體的例子:

#include <cassert>
#include <vector>

template <class T>
void
test(std::vector<T>& v)
{
    using const_ref = typename std::vector<T>::const_reference;
    const std::vector<T>& cv = v;
    const_ref cr = cv[0];
    assert(cr == cv[0]);
    v[0] = 1;
    assert(true == cv[0]);
    assert(cr == cv[0]);  // Fires!
}

int
main()
{
    std::vector<char> vc(1);
    test(vc);
    std::vector<bool> vb(1);
    test(vb);
}

標准規范說斷言標記// Fires! 將觸發,但僅當使用vector<bool>運行test時。 當使用vector<char> (或者在分配了適當的非默認T時除了bool之外的任何vector )運行時,測試通過。

libc ++實現試圖最小化vector<bool>在通用代碼中表現不同的負面影響。 它實現這一點的一件事是使vector<T>::const_reference成為代理引用 ,就像指定的vector<T>::reference ,除了你不能通過它分配。 也就是說,在libc ++上, vector<T>::const_reference本質上是指向vector內部位的指針,而不是該位的副本。

在libc ++上,上面的test傳遞了vector<char>vector<bool>

費用是多少?

缺點是這個擴展是可檢測的,如問題所示。 但是,很少有程序真正關心這個別名的確切類型,更多的程序關心這個行為。

這種不合格的動機是什么?

為了使libc ++客戶端能夠在通用代碼中獲得更好的行為,並且可能在經過充分的現場測試之后,將此擴展建議用於未來的C ++標准,以改善整個C ++行業。

這樣的提議可能以新容器(例如bit_vector )的形式出現,它具有與今天的vector<bool>大致相同的API,但是有一些升級,例如這里討論的const_reference 其次是vector<bool>專門化的棄用(並最終刪除)。 bitset也可以在這個部門使用一點升級,例如添加const_reference和一組迭代器。

也就是說,事后看來bitsetvector<bool> (應該重命名為bit_vector - 或者其他),因為arrayvector 無論我們是否將bool稱為vectorarrayvalue_type ,這個類比都應該成立。

有許多C ++ 11和C ++ 14特性的例子最初是作為libc ++中的擴展而開始的。 這就是標准的演變過程。 實際證明的 積極的實地經驗具有很強的影 當涉及到改變現有規范時,標准民眾是保守派(因為它們應該是這樣)。 即使您確定自己正確猜測,猜測也是制定國際公認標准的風險策略。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM