![](/img/trans.png)
[英]Why vector<bool>::reference doesn't return reference to 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
和一組迭代器。
也就是說,事后看來bitset
是vector<bool>
(應該重命名為bit_vector
- 或者其他),因為array
是vector
。 無論我們是否將bool
稱為vector
和array
的value_type
,這個類比都應該成立。
有許多C ++ 11和C ++ 14特性的例子最初是作為libc ++中的擴展而開始的。 這就是標准的演變過程。 實際證明的 積極的實地經驗具有很強的影 當涉及到改變現有規范時,標准民眾是保守派(因為它們應該是這樣)。 即使您確定自己正確猜測,猜測也是制定國際公認標准的風險策略。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.