Visual C++ 11 の新しい機能 のひとつに
「SCARY iterator(おっかないイテレータ)」てーのを見つけましてね。
なんじゃそりゃ? ってんで調べてみた。
#include <iostream>
#include <functional>
#include <set>
#include <typeinfo>
using namespace std;
int main() {
set<int,less<int>> a;
set<int,greater<int>> b;
cout << typeid(a.begin()).name() << endl;
cout << typeid(b.begin()).name() << endl;
}
コレ↑をvc10(Visual Studio 2010) で実行すると:
class std::_Tree_const_iterator<class std::_Tree_val<class std::_Tset_traits<int,struct std::less<int>,class std::allocator<int>,0> > >
class std::_Tree_const_iterator<class std::_Tree_val<class std::_Tset_traits<int,struct
std::greater<int>,class std::allocator<int>,0> > >
イテレータ型の中に比較オブジェクト(とアロケータ)が埋め込まれてて、両者は別物です。
一方vc11(Visual Studio 2012)だと:
class std::_Tree_const_iterator<class std::_Tree_val<struct std::_Tree_simple_types<int> > >
class std::_Tree_const_iterator<class std::_Tree_val<struct std::_Tree_simple_types<int> > >
両者の型は同じなの。
ってことは、要素の型が同じなら(比較オブジェクト/アロケータがどうであれ)ひとつのイテレータを使いまわせます。
set<X,なんやら> a;
set<X,かんやら> b;
set<X>::iterator iter;
iter = a.begin(); // ok
iter = b.begin(); // ok
...なるほどね。
ときにこの" SCARY"なんだが、これの書かれたドキュメントN2980によると:
N2911 explains that the acronym SCARY “describes assignments and initializations that are Seemingly erroneous (Constrained by conflicting generic parameters), but Actually work with the Right implementation (unconstrained bY the conflict due to minimized dependencies).”
ぱっと見マチガイみたいだけどちゃんと動くからいいじゃない
てゆー、めちゃめちゃ苦しいアクロニムなんだとさ。