【C++】コンテナを渡したらイテレータを返し、配列を渡したらポインタを返す
std:begin()
やstd::end()
の戻り値を受ける変数を宣言するために使います。大抵はauto
で対応できるものですが、auto
が使えないケースで使いたかったので作ってみました。SFINAEとか考える必要もなく、意外と簡単に実装できます。
実装と使用例
実装
#include <iterator>
#include <utility>
template <typename T>
struct GetIteratorImpl
{
using iterator = decltype(std::begin(std::declval<T &>()));
using reference = typename std::iterator_traits<iterator>::reference;
using value_type = typename std::iterator_traits<iterator>::value_type;
using pointer = typename std::iterator_traits<iterator>::pointer;
};
template <typename T>
using GetIterator = typename GetIteratorImpl<T>::iterator;
template <typename T>
using GetReference = typename GetIteratorImpl<T>::reference;
template <typename T>
using GetValueType = typename GetIteratorImpl<T>::value_type;
template <typename T>
using GetPointer = typename _GetIteratorImpl<T>::pointer;
std::begin()
やstd::end()
の戻り値を受けたいので、decltype()
でstd::begin()
の戻り値を指定します。ただ、これだけだとオーバーロードの解決ができません。std::declval<>()
をstd::begin()
の引数に指定することで、テンプレート引数T
を明示し、オーバーロードを解決します。また、std::begin()
の引数は左辺値参照なので、std::declval<T &>()
と&
を付けておく必要があります。
おまけで、std::iterator_traits<>
を使って、要素の型や、要素への参照型、要素へのポインタも取得できるようにしてみました。
使用例
使い道は少ないですが、auto
が使えない状況、たとえばテンプレートを使ったクラスのメンバ変数の型としてイテレータやポインタが必要な場合に使えます。
template <typename T>
class SampleClass
{
:
GetIterator<T> iter_;
:
};
ディスカッション
コメント一覧
まだ、コメントがありません