
MB wrote:
Hi,
Under VC++7.1, I was surprised that a class derived from 'boost::iterator_range' was almost copied by BOOST_FOREACH. ('boost::noncopyable' works!)
I think such a range that is noncopyable but derived from iterator_range is valid, isn't it ...? I think it could be dangerous if users can't find cheap_copy-customization.
Hrm, right. I feel some explanation is in order. The support for const rvalue detection is not without runtime cost, and it's all to avoid needless copying of expensive range-like objects such as STL containers. But when the range is something small like a boost::iterator_range, jumping through hoops of fire to avoid copying one is just silly. Hence the cheap_copy hack: BOOST_FOREACH has an optimized code path for types it knows (or believes to be) cheap to copy. You have run afoul of the cheap_copy optimization. Rightly or wrongly, it assumes types derived from boost::iterator_range are cheap to copy, but that's not the case for you. There are two possible fixes, and they both involve documenting the cheap_copy customization point (and probably fixing it to use ADL like boost::begin()): 1) By default, only apply the optimization to boost:iterator_range and its ilk, NOT to types derived from them. 2) Leave the code as it is, and force people in your situation to use the cheap_copy customization point to disable the optimization. I currently lean toward (1). -- Eric Niebler Boost Consulting www.boost-consulting.com