Reputation: 91
using HT = std::map<int, int*>;
class ITERATOR_PROXY
{
public:
ITERATOR_PROXY(HT& container) : m_container(container) { }
auto begin() const { return HT_ITERATOR_WRAPPER(std::begin(m_container)); }
auto end() const { return HT_ITERATOR_WRAPPER(std::end(m_container)); }
private:
struct HT_ITERATOR_WRAPPER
{
HT_ITERATOR_WRAPPER(HT::const_iterator iter_) : iter(iter_) {}
bool operator!=(const HT_ITERATOR_WRAPPER& other) const { return iter != other.iter; }
auto& operator*()
{
//const int& key=iter->first;
//int& val = *(iter->second);
// how to return (key, val) which would allow possible modification?
}
void operator++() { ++iter; }
HT::const_iterator iter;
};
HT& m_container;
};
int main()
{
HT ht;
std::array<int, 5> val = {0,1,2,3,4};
for (int i = 0; i < 5; ++i) ht[i] = &val[i];
ITERATOR_PROXY htw(ht);
for(auto x : htw)
{
//should not be changing val's original values
x.second += 100;
}
for(auto& x : htw)
{
// ok, changes the values in val array
x.second += 100;
}
for(const auto& x : htw)
{
// I should expect a compile error in this case
x.second += 100;
}
}
I want to have some way of using range-based for
loops with the map
container, which changes the original value type from int*
to int&
inside the loop (expected use cases in main()
).
I have been having some difficulty implementing the HT_ITERATOR_WRAPPER::operator*
. What should it return in this case? My feeling is I need to store the dereferenced element somewhere and have operator*
return a reference to it, but I am not sure how to make that work.
Edit: please note that I am looking to have operator * return references to both iter->firsts, and *(iter->second). This pair structure is in fact what *iter would return for associative containers.
Upvotes: 1
Views: 207
Reputation: 519
It should return *iter;
:
auto& operator*(){
return *iter;
}
EDIT: If you want to dereference the underlying value, go with what @RemyLebeau said and do this:
int& operator*(){
return *(iter->second);
}
ANOTHER EDIT: If you want both values, then the best your going to get is this (NOTE: I have not tried this):
std::pair<int&, int&> operator*(){
return std::make_pair<int&,int&>(iter->first, *iter->second);
}
Upvotes: 1