よく知られvector<bool>
ているように、プライマリ テンプレートと比較して非汎用のインターフェイスvector<T>
を備えています。
関連する違いは、ネストされた型reference
とconst_reference
が一般的なケースではtypedef
forT&
とであり、プロキシ クラスと値の型が であることです。T const&
reference
bool
vector<bool>
ベクトル要素にアクセスするときは、ベクトル オブジェクトの constness によってreference
、またはconst_reference
が返されるかどうかが決まることを覚えておくことも重要operator[]
です。さらに、auto
参照修飾子を削除しますdecltype
が、それらは保持します。
/ の非 const / const ベクトルを見て、 、 and を使用してみましょうbool
(プレーンはint
プロキシのライブタイムの問題につながります)。次の動作が得られます。auto
decltype(auto)
auto const&
auto&
#include <vector>
#include <type_traits>
#include <typeinfo>
#include <iostream>
#include <ios>
int main() {
using namespace std;
vector<bool> vb = { true, false, true, false };
vector<int > vi = { 1, 0, 1, 0 };
auto vb2 = vb[2]; // vector<bool>::reference != bool
auto vi2 = vi[2]; // int
decltype(auto) rvb2 = vb[2]; // vector<bool>::reference
decltype(auto) rvi2 = vi[2]; // int&
auto const& crvb2 = vb[2]; // vector<bool>::reference const& != bool const&
auto const& crvi2 = vi[2]; // int const&
auto ovb2 = vb2;
ovb2 = false; // OOPS ovb2 has reference semantics
cout << boolalpha << (vb[2] == true) << "\n";
auto ovi2 = vi2;
ovi2 = 0; // OK, ovi2 has value semantics
cout << boolalpha << (vi[2] == 1) << "\n";
static_assert(is_convertible<decltype(vb2), vector<bool>::value_type>::value, "");
static_assert(is_same <decltype(vi2), vector<int >::value_type>::value, "");
static_assert(is_same <decltype(rvb2), vector<bool>::reference>::value, "");
static_assert(is_same <decltype(rvi2), vector<int >::reference>::value, "");
static_assert(is_convertible<decltype(crvb2), vector<bool>::const_reference>::value, "");
static_assert(is_same <decltype(crvi2), vector<int >::const_reference>::value, "");
vector<bool> const cvb = { true, false, true, false };
vector<int > const cvi = { 1, 0, 1, 0 };
auto cvb2 = cvb[2]; // vector<bool>::const_reference == bool
auto cvi2 = cvi[2]; // int
decltype(auto) rcvb2 = cvb[2]; // vector<bool>::const_reference == bool
decltype(auto) rcvi2 = cvi[2]; // int const&
auto const& crcvb2 = cvb[2]; // vector<bool>::reference const& != bool const&
auto const& crcvi2 = cvi[2]; // int const&
static_assert(is_same <decltype(cvb2), vector<bool>::value_type>::value, "");
static_assert(is_same <decltype(cvi2), vector<int >::value_type>::value, "");
static_assert(is_same <decltype(rcvb2), vector<bool>::const_reference>::value, "");
static_assert(is_same <decltype(rcvi2), vector<int >::const_reference>::value, "");
static_assert(is_convertible<decltype(crcvb2), vector<bool>::const_reference>::value, "");
static_assert(is_same <decltype(crcvi2), vector<int >::const_reference>::value, "");
auto ocvb2 = cvb2;
ocvb2 = false; // OK, ocvb2 has value semantics
cout << boolalpha << (cvb[2] == true) << "\n";
auto ocvi2 = cvi2;
ocvi2 = 0; // OK, ocvi2 has value semantics
cout << boolalpha << (cvi[2] == 1) << "\n";
}
実際の例
非 constの場合、 onをvector<bool>
使用すると、値のセマンティクスを持たない参照プロキシが得られることに注意してください。a を使用すると、それを回避できます。これを他の方法で解決する方法がわかりません。auto
operator[]
const vector<bool>
はauto const&
動作的に同等ですが、 の中にis_convertible
ではなく があります。私はこれができる最善の方法だと思います。is_same
static_assert
プロキシ コンテナーでの一般的な反復と STL アルゴリズムの場合、状況はそれほど暗くないことに注意してください。これに関する Hinnant のコラムを参照してください。