std::begin
およびの1つの利点は、std::end
外部クラスの標準インターフェースを実装するための拡張ポイントとして機能することです。
あなたが使用したい場合CustomContainer
と、クラスを期待ループまたはテンプレート関数の範囲をベース.begin()
と.end()
する方法は、あなたが明らかにそれらのメソッドを実装する必要があると思います。
クラスがこれらのメソッドを提供する場合、それは問題ではありません。そうでない場合は、変更する必要があります*。
これは、たとえば外部ライブラリ、特に商用およびクローズドソースのライブラリを使用する場合など、常に実現可能であるとは限りません。
このような状況で、std::begin
かつstd::end
1は、クラス自体を変更するのではなく、自由な関数をオーバーロードすることなく、イテレータAPIを提供することができるので、便利になります。
例:count_if
1組のイテレーターの代わりにコンテナーを取る関数を実装するとします。このようなコードは次のようになります。
template<typename ContainerType, typename PredicateType>
std::size_t count_if(const ContainerType& container, PredicateType&& predicate)
{
using std::begin;
using std::end;
return std::count_if(begin(container), end(container),
std::forward<PredicateType&&>(predicate));
}
これで、このカスタムcount_if
で使用するクラスの場合、これらのクラスを変更する代わりに、2つの無料の関数を追加するだけで済みます。
現在、C ++にはArgument Dependent Lookup
(ADL)と呼ばれるメカニズムがあり、そのようなアプローチをさらに柔軟にしています。
つまり、ADLは、コンパイラが修飾されていない関数(つまり、begin
ではなく名前空間のない関数)を解決するときstd::begin
に、引数の名前空間で宣言された関数も考慮することを意味します。例えば:
namesapce some_lib
{
// let's assume that CustomContainer stores elements sequentially,
// and has data() and size() methods, but not begin() and end() methods:
class CustomContainer
{
...
};
}
namespace some_lib
{
const Element* begin(const CustomContainer& c)
{
return c.data();
}
const Element* end(const CustomContainer& c)
{
return c.data() + c.size();
}
}
// somewhere else:
CustomContainer c;
std::size_t n = count_if(c, somePredicate);
この場合、その修飾名がある問題ではないsome_lib::begin
とsome_lib::end
するので- CustomContainer
であるsome_lib::
、あまりにも、コンパイラは、それらの中のオーバーロードを使用しますcount_if
。
それはまた、ある理由だusing std::begin;
とusing std::end;
の中でcount_if
。これは、私たちは修飾されていない使用することができますbegin
し、end
したがって、ADLを可能にし、
コンパイラが選択できるようにするstd::begin
とstd::end
、他の代替案が見つからないとき。
Cookieを食べてCookieを取得できます。つまり、begin
/のカスタム実装を提供する方法があるend
一方で、コンパイラは標準のCookieにフォールバックできます。
いくつかのメモ:
同じ理由で、他の同様の関数があります:std::rbegin
/ rend
、
std::size
およびstd::data
。
他の回答が述べているように、std::
バージョンにはネイキッド配列のオーバーロードがあります。これは便利ですが、上で説明したことの単なる特別なケースです。
std::begin
テンプレートコードを記述する場合は、や友人を使用することをお勧めします。これにより、これらのテンプレートがより汎用的になるためです。非テンプレートの場合は、該当する場合はメソッドも使用できます。
PS私はこの投稿が7歳近くであることを知っています。重複としてマークされた質問に答えたくて、ここでADLについて言及している答えがないことに気付いたので、私はそれに遭遇しました。