autoとdecltypeで楽がしたい
C++03の世界では、mapのiterator作ろうとするとこれえらい量を冗長な感じでタイプしなければならなかったが、C++11から導入されたdecltype使うとなんか…C++なのにふつくしい、そんなコードに思えてきたっつー話。
例えば
std::map<int, std::string>::iterator getIterator(std::map<int, std::string> & x) { return x.find(0); }
って書いていたものが、
auto getIterator11(std::map<int, std::string> & x) -> delete_reference<decltype(x)>::type::iterator { return x.find(0); }
と書けるわけです。これでmapのstd::stringが突然charに変わるような仕様変更でも関数の引数を直すだけでよいわけです。冗長性の排除ふつくしい。
delete_referenceは自作の参照外し構造体。こちらもお勉強兼ねて作っただけで、通常は標準ライブラリのremove_reference使えばよい。
↓コード全体
#include <iostream> #include <string> #include <map> //referenceはずし template<class T> struct delete_reference { typedef T type; }; template<class T> struct delete_reference<T&> { typedef T type; }; std::map<int, std::string>::iterator getIterator(std::map<int, std::string> & x) { return x.find(0); } auto getIterator11(std::map<int, std::string> & x) -> delete_reference<decltype(x)>::type::iterator { return x.find(0); } int main() { std::map<int, std::string> map; map[0] = "A"; map[1] = "B"; map[2] = "C"; std::map<int, std::string>::iterator x1 = getIterator(map); auto x2 = getIterator11(map); std::cout << "x1:" << x1->second << std::endl; std::cout << "x2:" << x2->second << std::endl; return 0; }
実行結果は
x1:A x2:A
どちらも同じだよと。