std::unordered_mapやstd::mapの比較用のファンクタとしてラムダ式を渡す
やろうとして意外に面倒だった。が、だれも書いていないみたいなので書いておく。より面倒なのはstd::unordered_mapのほうなのでこちらについて主に書く。
面倒なのは基本的にテンプレート引数としてファンクタを渡す仕様になっているということ。ラムダ式は型ではないので当然テンプレート引数として渡すことができない。しかも、デフォルトの型というのがラムダ式を受け取れるような型ではない(std::equal_to
あれこれいっててもわかりにくいと思うのでサンプルをあげておく。これをみればわかるようにとある事情でstd::stringではなくconst char*をキーにしたかったわけだがその比較のためにファンクタをわたす必要があった。
#include<iostream> #include<unordered_map> #include<functional> int main(){ std::unordered_map<const char*, const char*,std::hash<const char*>,std::function<bool(const char*, const char*)> > Map ( 0, std::hash<const char*>(), [](const char* lhs,const char* rhs){return (strcmp(lhs, rhs) == 0)? true : false;} ) ; Map["hoge"]="aa"; Map["bar"]="ab"; std::cout<< Map["bar"] << std::endl; std::cout<< Map["hoge"] << std::endl; return 0; }
std::mapのほうはハッシュ関数を指定しなくていいので多少楽だ。第三テンプレート引数にstd::functionを指定するだけで普通に渡せるようになる。
#include<iostream> #include<functional> #include<map> int main(){ std::map<const char*, const char*,std::function<bool(const char*, const char*)> > Map( [](const char* lhs,const char* rhs){return (strcmp(lhs, rhs) == 0)? true : false;} ); Map["hoge"]="aa"; Map["bar"]="ab"; std::cout<< Map["bar"] << std::endl; return 0; }
たぶん、ラムダ式が存在しない時代はテンプレートで指定できるほうが便利だったのだろう。しかし今となっては逆に面倒だ。せめてstd::function