|
Boost Users : |
From: abir basak (abirbasak_at_[hidden])
Date: 2006-11-21 01:04:17
Thorsten Ottosen wrote:
> abir basak wrote:
>> Thorsten Ottosen wrote:
>
>>> This is an error in the range lib that should be fixed in the upcoming
>>> version of boost.
>> Is the correction is in the CVS head ?
>
> Should be. Try it out and let me know the result.
Checked with the boost cvs version (downloaded only range library, i.e.
only the files inside
the range folder , and the range.hpp file ).
It gives the same kind of error in little different manner.
For the line like,
boost::sub_range<const VI> r1(v.begin()+2,v.begin()+8);
or
boost::sub_range<const VI> r1(cv.begin()+2,cv.begin()+8);
(The code is with reference to last post )
Gives error for the statement
cout<<r1[1]<<endl; (i.e access by index)
as (in my VC 2003 compiler , version 7.1)
e:\boost_1_33_1\boost\range\sub_range.hpp(133): error C2440: 'return' :
cannot convert from 'const std::allocator<_Ty>::value_type' to
'boost::sub_range<ForwardRange>::value_type &'
with
[
_Ty=int
]
and
[
ForwardRange=const VI
]
Conversion loses qualifiers
e:\boost_1_33_1\boost\range\sub_range.hpp(132) : while
compiling class-template member function
'boost::sub_range<ForwardRange>::value_type
&boost::sub_range<ForwardRange>::operator
[](boost::sub_range<ForwardRange>::size_type)'
with
[
ForwardRange=const VI
]
f:\abir\programs\Test\main.cpp(253) : see reference to class
template instantiation 'boost::sub_range<ForwardRange>' being compiled
with
[
ForwardRange=const VI
]
Quickly going through the code, I see it calls
value_type& operator[]( size_type sz )
{
return base::operator[](sz);
}
for a sub_range with const container, which returns value_type& rather
than const value_type& . It fails in a way, that it don't know whether
container is const or not (though it knows iterators are const or not).
And, it perfectly works, as expected if the code is modified like,
const boost::sub_range<const VI> r1(v.begin()+2,v.begin()+8); ///note
the range is also made const along with the container.
as it now calls,
const value_type& operator[]( size_type sz ) const
{
return base::operator[](sz);
}
Thus const_sub_range is not like "sub_range<const container_type>",
rather strangely it is "const sub_range<const container_type>"
which is little different that the iterator concept.
The problem lies is that a const_sub_range is not same as const
sub_range, just like const_iterator is not same as const iterator. For
const_iterator, even non const member function need to return a
const_reference, and should be same for sub_range.
I am not sure, how a single class can know the const-ness of the
container, and hence invoke additional method, without passing an
additional argument or having two different class.
For second type, it may be the same as the way SGI iterator and
const_iterator are implemented.
The first way is to have a sub_range template definition as,
template<typename container_type, typename elem_type =
container::value_type>
and then return elem_type for the operators, irrespective of const-ness
of the member function.
The user has the responsibility to say it explicitly like
boost::sub_range<VI> r(...); ///for non const version.
boost::sub_range<const VI,VI::const_reference> r(...); ///for const version.
I think, as most of the STL containers internally do this as typedef,
and return iterator by themselves, it is not a problem.
However when the sub_range is returned "externally using the container",
I am not sure any other method works for const version.
I will be glad if someone can show a way to know where a template
parameter is const, as that will help me in many other part of the codes
also (I am little fond of const-ness and use it as much as possible).
Thanks to the Boost community.
abir basak
> -Thorsten
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net