for_eachは、Non-modifying sequence operationsということになっている。では、たとえばこういうコードは、規格違反なのだろうか。
template < typename Iterator > void f( Iterator first, Iterator last ) { std::for_each(first, last, []( std::iterator_traits<Iterator>::reference value) { value = std::iterator_traits<Iterator>::value_type() ; // 書き換える。 } ) ; }
std::iterator_traits<Iterator>::value_typeは、デフォルトコンストラクタと、コピーコンストラクタを持つものとする。このように、参照で受ければ、for_eachで、イテレーターの指す要素を書き換えることが可能だ。
じつは、規格には、mutable iteratorというものがある。これは、あるイテレーターの変数、iに対して、*iという式が、リファレンスを返すイテレーターのことを指す。その場合、for_eachで、イテレーターの指す要素を書き換えることができるのである。
なぜリファレンスでなければならないのか。それは、こういう事だ。
struct Iterator { int operator *() ; }
このように、operator *()がリファレンスを返さなければ、いくら関数オブジェクトの仮引数をlvalueリファレンスで受けても、書き換えることはできない。
No comments:
Post a Comment
You can use some HTML elements, such as <b>, <i>, <a>, also, some characters need to be entity referenced such as <, > and & Your comment may need to be confirmed by blog author. Your comment will be published under GFDL 1.3 or later license with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.