
Eric Niebler skrev:
General design question here. This came up on the user's list, and it made me question something I believed to be true. When writing a proxy for, e.g., a std container, I see two options for handling const.
0) Const-ness depends on the const-ness of the object being proxied:
struct vector_proxy { std::vector<int> & vec; typedef std::vector<int>::iterator iterator; typedef std::vector<int>::iterator const_iterator; iterator begin() const { return vec.begin(); } ... };
1) Const-ness depends on the proxy object itself:
struct vector_proxy { std::vector<int> & vec; typedef std::vector<int>::iterator iterator; typedef std::vector<int>::const_iterator const_iterator; iterator begin() { return vec.begin(); } const_iterator begin() const { return vec.begin(); } ... };
I think a loooong time ago, I preferred (1) but these days (0) is more natural for me, but I can't say why, exactly. Just feels like that's how it should be. Thoughts?
There's a relevant piece in Boost.Range: http://www.boost.org/libs/range/doc/utility_class.html boost::iterator_range falls into case 1, whereas boost::sub_range falls into case 2. I think case one has been the preferred way in C++0x3 because the language lacks rvalue references. Without rvalue references we often say template< class Range > void SomeAlgo( const iterator_range<Range>& ); Wiht rvalue references, I think option 2 will gain popularity. -Thorsten