(const_)iterator
基になる値の型へのポインターから構築可能であるという要件がないため、試みていることを実行するための移植可能な方法はありません。libstdc++ はたまたまそのようなコンストラクタを提供しますが、VS 標準ライブラリの実装は提供しません。代わりに、その(const_)iterator
コンストラクターは、基になる値の型へのポインターと、コンテナー自体へのポインターを受け取ります。これは、デバッグ ビルド中に追加の検証を実行するために使用されます。
最も簡単な解決策は、に置き換えることstd::vector<unsigned char>::const_iterator
ですunsigned char const *
。生のポインタは、s と同じ RandomAccessIterator カテゴリに分類されますvector::(const_)iterator
。
unsigned char const *foo::begin() {
return value;
}
unsigned char const *foo::end() {
return value + length;
}
イテレータをクラス型にする必要がある場合は、カスタム イテレータを作成する必要があります。これはゼロから行うこともできますが、Boost.IteratorFacadeを使用する方がはるかに簡単です。これは、カスタム イテレータの構築に必要な一連のボイラープレートを提供します。
#include <boost/iterator/iterator_facade.hpp>
struct const_foo_iterator : boost::iterator_facade<const_foo_iterator,
unsigned char const,
boost::random_access_traversal_tag>
{
const_foo_iterator() = default;
const_foo_iterator(unsigned char const *iter) : iter(iter) {}
private:
friend class boost::iterator_core_access;
void increment() { ++iter; }
void decrement() { --iter; }
void advance(std::ptrdiff_t n) { iter += n; }
std::ptrdiff_t distance_to(const_foo_iterator const& other) const
{ return iter - other.iter; }
bool equal(const_foo_iterator const& other) const
{ return this->iter == other.iter; }
unsigned char const& dereference() const { return *iter; }
unsigned char const* iter = nullptr;
};
const_foo_iterator foo::begin() {
return value;
}
const_foo_iterator foo::end() {
return value + length;
}
static_assert(std::is_same<std::iterator_traits<const_foo_iterator>::value_type,
unsigned char>::value, "value_type");
static_assert(std::is_same<std::iterator_traits<const_foo_iterator>::pointer,
unsigned char const *>::value, "pointer");
static_assert(std::is_same<std::iterator_traits<const_foo_iterator>::iterator_category,
std::random_access_iterator_tag>::value, "iterator_category");
ライブデモ