Uygun bir program tarafından tespit edilebilen ve dolayısıyla uygun olmayan bu uzantının motivasyonu, referanslara göre (const ve diğer) vector<bool>
daha çok davranmaktır vector<char>
.
Giriş
1998'den vector<bool>
beri "pek kapsayıcı değil" diye alay ediliyor. İlk LWG sorunlarından biri olan LWG 96 , tartışmayı başlattı. Bugün, 17 yıl sonra, vector<bool>
büyük ölçüde değişmeden kalır.
Bu makale , davranışının vector<bool>
diğer tüm somutlaştırmalardan nasıl farklılaştığına ve vector
böylece genel koda zarar verdiğine dair bazı özel örneklere giriyor . Bununla birlikte, aynı makale, vector<bool>
düzgün bir şekilde uygulandığında çok güzel performans özelliklerinin sahip olabileceği uzun uzadıya tartışılmaktadır .
Özet : vector<bool>
kötü bir kap değil. Aslında oldukça kullanışlıdır. Sadece kötü bir adı var.
Geri dön const_reference
Yukarıda açıklandığı ve burada ayrıntılı olarak açıklandığı gibi, kötü olan şey vector<bool>
, genel kodda diğer vector
örneklerden farklı şekilde davranmasıdır . İşte somut bir örnek:
#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]);
}
int
main()
{
std::vector<char> vc(1);
test(vc);
std::vector<bool> vb(1);
test(vb);
}
Standart belirtim, işaretlenen iddianın // Fires!
tetikleneceğini, ancak yalnızca test
bir vector<bool>
. Bir ile çalıştırıldığında vector<char>
(veya herhangi bir vector
yanında bool
, uygun bir varsayılan olmayan zaman T
atanır), test başarılı olur.
Libc ++ uygulaması vector<bool>
, genel kodda farklı davranmanın olumsuz etkilerini en aza indirmeye çalıştı . Bunu başarmak için yaptığı bir şey , tıpkı belirtilen gibi vector<T>::const_reference
bir vekil referansı yapmaktır vector<T>::reference
, ancak bunun dışında atayamazsınız. Yani, libc ++ 'da vector<T>::const_reference
, aslında vector
o bitin bir kopyası yerine içindeki biti gösteren bir göstericidir .
Libc ++ 'da yukarıdakiler test
hem vector<char>
ve hem de vector<bool>
.
Ne pahasına?
Olumsuz yanı, soruda gösterildiği gibi bu uzantının algılanabilir olmasıdır. Ancak, çok az program aslında bu takma adın tam türünü önemsemekte ve daha fazla program davranışı önemsemektedir.
Bu uyumsuzluğun nedeni nedir?
Libc ++ istemcisine genel kodda daha iyi davranış sağlamak için ve belki de yeterli alan testinden sonra, bu uzantıyı tüm C ++ endüstrisinin iyileştirilmesi için gelecekteki bir C ++ standardına önerin.
Böyle bir öneri bit_vector
, bugünkü API ile hemen hemen aynı API'ye vector<bool>
sahip, ancak const_reference
burada tartışılanlar gibi birkaç yükseltmeye sahip yeni bir kapsayıcı (örneğin ) biçiminde gelebilir . Ardından vector<bool>
uzmanlığın kullanımdan kaldırılması (ve sonunda kaldırılması) . bitset
ayrıca bu bölümde biraz yükseltme, örneğin ekleme const_reference
ve bir dizi yineleyici kullanabilir.
Gez içinde bir deyişle, bitset
etmektir vector<bool>
(hangi adlandırılması bit_vector
gibi - ya da her neyse) array
etmektir vector
. Ve benzetme bahsediyoruz olsun veya olmasın doğru çıkması gerektiğini bool
olarak value_type
bir vector
ve array
.
Libc ++ 'da uzantılar olarak başlayan C ++ 11 ve C ++ 14 özelliklerinin birçok örneği vardır. Standartlar bu şekilde gelişir. Gerçek olarak gösterilen pozitif saha deneyimi, güçlü bir etkiye sahiptir. Standartlar, mevcut spesifikasyonları (olması gerektiği gibi) değiştirmek söz konusu olduğunda muhafazakar bir gruptur. Doğru tahmin ettiğinizden emin olsanız bile tahmin etmek, uluslararası kabul görmüş bir standardı geliştirmek için riskli bir stratejidir.
vector<bool>
daha birinci sınıf bir temel oluşturabilir mi?