【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_;
:
};


ディスカッション
コメント一覧
まだ、コメントがありません