の要素std::initializer_list
が常にconst値である場合、なぜではbegin()/end()
なくのようなテンプレートメソッドがあるのcbegin()/cend()
ですか?この名前(慣例により、egと比較して)は、両方のメソッドが常に。を返す場合に、両方のメソッドがを返す可能std::vector
性があることを示唆している可能性があります。std::initializer_list
iterator
const_iterator
1 に答える
とに加えてのインターフェイスの一部ではないcbegin()
理由についての洞察を提供することはできませんが、最後の2つのメンバー関数がそこにあるべきである理由は確かにあります。cend()
std::initializer_list
begin()
end()
1つの理由は、たとえば、範囲ベースのループが関数と(段落6.5.4 / 1)for
の観点からC++11標準によって正確に定義されていることです。したがって、初期化子リストで使用できるようにするには、およびメンバー関数を提供する必要があります。begin()
end()
std::initializer_list
begin()
end()
#include <utility>
#include <iostream>
int main()
{
auto l = { 1, 2, 3, 4, 5 };
for (int x : l) // Works because std::initializer_list provides
// the member functions begin() and end().
{
std::cout << x << " ";
}
}
さらに、メンバー関数はC ++ 11より前には存在cbegin()
していなかったと考えるのは理にかなっています。したがって、のインターフェイスを使用すると、初期化リストに関して記述された古い汎用アルゴリズムを作成し、初期化リストを使用する必要がなくなります。書き直しました。cend()
begin()
end()
std::initializer_list
begin()
end()
あなたが書く:
これらの名前(慣例により、egと比較して)は、常に。を返す場合、
std::vector
両方のstd::initializer_list
メソッドがを返す可能性があることを示唆している可能性があります。iterator
const_iterator
実際、このアナロジーはあまり適切ではありません。std::vector
たとえば、の関数は、の非インスタンス(つまり、要素を変更、追加、および削除できる可変のインスタンス)で呼び出されたときと、インスタンス(つまり、コンテンツが不変のインスタンス)で呼び出されbegin()
たときを返します。変更できません):iterator
const
std::vector
const_iterator
const
#include <vector>
#include <type_traits>
int main()
{
// A non-const vector...
std::vector<int> v = { 1, 2, 3, 4, 5 };
auto i = v.begin();
static_assert(
std::is_same<decltype(i), decltype(v)::iterator>::value,
// ^^^^^^^^
// ...non-const iterator!
"What?");
// A const vector...
std::vector<int> const vc = { 1, 2, 3, 4, 5 };
auto ic = vc.begin();
static_assert(
std::is_same<decltype(ic), decltype(vc)::const_iterator>::value,
// ^^^^^^^^^^^^^^
// ...const iterator!
"What?");
}
イニシャライザリストは、定義上、不変のコレクションです。C++11規格のパラグラフ18.9/2による:
タイプのオブジェクトは、タイプ
initializer_list<E>
のオブジェクトの配列へのアクセスを提供しますconst E
。[...]
初期化子リストはconst
要素のコレクションであるため、cbegin()
およびcend()
関数は実際にはとまったく同じことを実行begin()
しend()
ます。
実際、iterator
とconst_iterator
は両方とも初期化子リストの値型の定数要素へのポインターとして定義されているので、それが常に返されるのか(あなたが想定しているように)、または常に返されるのかは議論の余地がbegin()
あります。end()
const_iterator
iterator
これは、C++11標準の段落18.9/1がinitializer_list
クラステンプレートを定義する方法です。
namespace std {
template<class E> class initializer_list {
public:
typedef E value_type;
// ...
typedef const E* iterator;
typedef const E* const_iterator;
// ...
constexpr const E* begin() const noexcept; // first element
constexpr const E* end() const noexcept; // one past the last element
};
// ...
}