[range] sub_range assignment issue

The following simple problem produces an error when compiling with VC8+SP1 on Windows: #include <vector> #include <boost/range/sub_range.hpp> int main(int argc, char* argv[]) { typedef std::vector< int > VectorType; VectorType v; boost::sub_range< VectorType > range; boost::sub_range< VectorType > range1; range = range1; return 0; } boost\boost\range\iterator_range.hpp(60) : error C2440: '<function-style-cast>' : cannot convert from 'std::_Vector_const_iterator<_Ty,_Alloc>' to 'std::_Vector_iterator<_Ty,_Alloc>' 1> with 1> [ 1> _Ty=int, 1> _Alloc=std::allocator<int> 1> ] 1> No constructor could take the source type, or constructor overload resolution was ambiguous This happens with both 1.34.1 and trunk but 1.33 is OK. Regards, Sean

Sean Huang wrote:
The following simple problem produces an error when compiling with VC8+SP1 on Windows:
#include <vector> #include <boost/range/sub_range.hpp>
int main(int argc, char* argv[]) { typedef std::vector< int > VectorType; VectorType v; boost::sub_range< VectorType > range; boost::sub_range< VectorType > range1; range = range1; return 0; }
sub_range copy-constructor is broken under msvc. (BTW, a singular(uninitialized) sub_range can't be assigned to another.) I've ever looked into this problem. See: The implicitly-defined coyp-constructor shall be something like this: sub_range(sub_range const &from) : super(static_cast<super const &>(from)) // calls "normal" copy-constructor of super type. { } But I guess msvc8(maybe also msvc7.1) generates: sub_range(sub_range const &from) : super(from) // overload resolution of super type constructors kicks in. { } super type(iterator_range) doesn't know the sub_range type. Now sub_range is const-qualified, hence it can't be copied to mutable iterators. Ditto copy-assignment operator. The workaround is to write copy-constructor/assignment "by hand". In fact, this can't explain the exact behavior of msvc. My sub_range seems to work well, though. Regards, -- Shunsuke Sogame

shunsuke skrev:
The workaround is to write copy-constructor/assignment "by hand".
In fact, this can't explain the exact behavior of msvc. My sub_range seems to work well, though.
Thanks for the feedback, shunsuke. I will update the subversion version to reflact that. best regards -Thorsten

The following simple problem produces an error when compiling with VC8+SP1 on Windows:
#include <vector> #include <boost/range/sub_range.hpp>
int main(int argc, char* argv[]) { typedef std::vector< int > VectorType; VectorType v; boost::sub_range< VectorType > range; boost::sub_range< VectorType > range1; range = range1; return 0; }
Ditto copy-assignment operator. The workaround is to write copy-constructor/assignment "by hand".
In fact, this can't explain the exact behavior of msvc. My sub_range seems to work well, though.
Shunsuke, Thanks for the analysis. I looked into this a bit more and found that the workaround added for VC7.1 is giving VC8 problems (by the way, it only happened in debug build, release build was fine). I removed the operator= that accepts sub_range r passed by value and everything started working. Specifically, I commented out the following code in sub_range.hpp: sub_range& operator=( sub_range r ) { // // argument passed by value to avoid // const_iterator to iterator conversion // base::operator=( r ); return *this; } Regards, Sean

Sean Huang wrote:
I removed the operator= that accepts sub_range r passed by value and everything started working.
This is because template< class ForwardRange2 > sub_range& operator=( ForwardRange2& r ) wins the overloading race against implicitly-defined copy-assignment operator. This behavior is conforming. Well, a templated constructor/assignment seems difficult to implement. FWIW, my sub_range is here :-) http://tinyurl.com/35s4wp Regards, -- Shunsuke Sogame
participants (3)
-
Sean Huang
-
shunsuke
-
Thorsten Ottosen