映射代理迭代器冲突 C++20 迭代器概念

时间:2021-04-27 19:24:37

标签: c++ iterator c++20 c++-concepts

我正在尝试编写一个包装类,它将 std::vector<T> 解释为整数到 T 的映射。因为我希望它表现得像一个 map,所以它的迭代器应该取消对 (key, value) 对的引用。由于内存中没有这样的对,我对应的迭代器类的 reference 类型有点不合常规:

  using value_type = std::pair<Key, Value>;
  using reference = std::pair<Key, Value&>;

对于对应的const_iterator,这变成

  using value_type = std::pair<Key, const Value>;
  using reference = std::pair<Key, const Value&>;

然而,现在我的 const_iterator 不再满足 std::indirectly_readable(因此,std::forward_iteratorstd::random_access_iterator),因为

no type named 'type' in 'struct std::common_reference<std::pair<long unsigned int, const int&>&&, std::pair<long unsigned int, const int>&>'

(参见 https://godbolt.org/z/s89z56rY7)或此处的完整代码:

#include <iostream>
#include <type_traits>
#include <vector>
#include <iterator>

using namespace std;

template<class Value, class VType, class RType>
struct _vector_map_iterator {
    Value* _data = nullptr;
    size_t index = 0;
    using value_type = VType;
    using reference = RType;
    using difference_type = ptrdiff_t;
    using iterator_category = std::random_access_iterator_tag;
    
    reference operator*() const { return {index, *_data}; }
    _vector_map_iterator& operator++() { ++index; return *this; }
    _vector_map_iterator operator++(int) {_vector_map_iterator res = *this; ++(*this); return res; }
    bool operator==(const _vector_map_iterator& other) const { return _data == other.data; }
};
template<class T>
using vmap_iterator = _vector_map_iterator<T, pair<size_t, T>, pair<size_t, T&>>;
template<class T>
using vmap_const_iterator = _vector_map_iterator<const T, pair<size_t, const T>, pair<size_t, const T&>>;

using I = vmap_const_iterator<int>;
//static_assert(std::common_reference_with<typename I::reference&&, typename I::value_type&>);
static_assert(forward_iterator<I>);

template<class Value>
struct vector_map {
    vector<Value> _raw_data;
    using iterator = vmap_iterator<Value>;
    using const_iterator = vmap_const_iterator<Value>;
    iterator begin() { return {_raw_data.data(), 0}; }
    const_iterator begin() const { return {_raw_data.data(), 0}; }
    vector_map(const initializer_list<Value>& lst): _raw_data(lst) {};
};

int main(){
    const vector_map<int> int_map = {1,2,3};
    const auto it =  int_map.begin();
    cout << (*it).first << ": " << (*it).second << '\n';
}

我的问题是:对于这样一个也遵守 std::random_access_iterator 的迭代器类,是否有一个明智的(我特别不想在向量中存储键值对!)设计?

编辑:更多细节+完整示例

0 个答案:

没有答案