2

I'm writing a range_map container, which stores data in ranges, allowing you to, pick a point and get the ranges that cover it. As a rule, when a range is inserted, its start point and end point must each be covered by the same ranges--causing a kind of pyramid buildup of ranges.

Ranges that are subsets of other ranges have those other ranges as parents. I'm just about done with it and am debugging it when I went through this weird problem. Here's a private method--it's a helper method--from the container, where the error occured:

std::pair<iterator, bool> _insert2(range_type&& _s, range_type&& _e) {
    std::pair<iterator, bool> _ret(end(), false);

    std::pair<iterator, bool> _temp = _myset.insert(std::forward<range_type>(_s));
    if(!_temp.second) return _ret;
    iterator _start = _temp.first;
    _temp = _myset.insert(std::forward<range_type>(_e));
    if(!_temp.second) {erase(_start); return _ret;}
    iterator _end = _temp.first;

    iterator _i = _start;
    for(++_i; _i != _end; ++_i) {
        if(_i->is_end) 
            _i->parent = _end;
        else
            _i->parent = _start;
    }

    _ret.first = _start;
    _ret.second = true;

    return _ret;
}

OK, iterator is typedef'd from the wrapped container's iterator.

  • range_type is the type that is stored in the wrapped container.
  • parent is the parent range, which is also stored as an iterator.

The problem is in the lines where _i->parent is assigned either _end or _start. It comes back with error c2678. Now, for me, this is in Japanese, but it says that the left operand for each of the two lines pointed is of the type const std::_Tree_const_iterator<_Mytree>; therefore, it cannot be assigned anything.

Why it considers the left operand to be a const const_iterator, I don't know, but that is the error. (parent, by the way, is declared as an iterator in range_type.) What's really funny is that in another method (a public method in the same class this time) I do the exact same thing with parent from an iterator and it appears to compile fine--this public method comes before the private method above in the code. Here is the public method:

iterator erase(const_iterator _iter) {
    iterator _mine = _myset.lower_bound(*_iter);
    iterator _start = _mine->is_end ? find_opposite_pt(_mine) : _mine;
    iterator _end = _mine->is_end ? _mine : find_opposite_pt(_mine);

    iterator _ps = _start->parent, _pe = _end->parent;
    iterator _i = _start;
    for(++_i; _i != _end; ++_i) 
        _i->parent = _i->is_end ? _pe : _ps;

    _myset.erase(_start);
    return _myset.erase(_end);
}

Though this method in the code comes before the one that gave the error, no error was given for the line where _i->parent was assigned a value.

What is going on here? Why does the iterator seem to morph into a const const_iterator? I hope I was detailed enough.

EDIT: Here's the rest of the output, translated:

   with
1>          [
1>              _Mytree=std::_Tree_val<std::_Tset_traits<range_map<int,int>::range_type,range_map<int,int>::value_compare,std::allocator<range_map<int,int>::range_type>,false>>
1>          ]
1>          c:\program files\microsoft visual studio 10.0\vc\include\xtree(337): It could be this: 'std::_Tree_const_iterator<_Mytree> &std::_Tree_const_iterator<_Mytree>::operator =(const std::_Tree_const_iterator<_Mytree> &)'.
1>          with
1>          [
1>              _Mytree=std::_Tree_val<std::_Tset_traits<range_map<int,int>::range_type,range_map<int,int>::value_compare,std::allocator<range_map<int,int>::range_type>,false>>
1>          ]
   If you combine the parameter list '(const std::_Tree_const_iterator<_Mytree>, std::_Tree_const_iterator<_Mytree>)'
   with
1>          [
1>              _Mytree=std::_Tree_val<std::_Tset_traits<range_map<int,int>::range_type,range_map<int,int>::value_compare,std::allocator<range_map<int,int>::range_type>,false>>
1>          ]
    c:\users\one\documents\visual studio 2010\projects\range_map_test\range_map_test\range_map.h(487): While compiling class template member method 'std::pair<_Ty1,_Ty2> range_map<_Kty,_Ty>::_insert2(range_map<_Kty,_Ty>::range_type &&,range_map<_Kty,_Ty>::range_type &&)'
   with
1>          [
1>              _Ty1=std::_Tree_const_iterator<std::_Tree_val<std::_Tset_traits<range_map<int,int>::range_type,range_map<int,int>::value_compare,std::allocator<range_map<int,int>::range_type>,false>>>,
1>              _Ty2=bool,
1>              _Kty=int,
1>              _Ty=int
1>          ]
1>          c:\users\one\documents\visual studio 2010\projects\range_map_test\range_map_test\main.cpp(6) : Please check the declaration of the instance of the template 'range_map<_Kty,_Ty>'
1>          with
1>          [
1>              _Kty=int,
1>              _Ty=int
1>          ]

This is so so cryptic. I can't make heads or tails of it, and I can't understand why the same didn't occur in that other function. Is it because it returns a pair with an iterator in it, or something? Some weird complex thing?

4

0 回答 0