2013-05-26 8 views
13

私はstd :: unordered_mapを見ていて、文字列をキーとして使用したい場合は、ファンクタを含むクラスを作成する必要があることがわかりました。テンプレートパラメータにラムダ関数を使用することはできますか?

好奇心で、私はラムダがこれの代わりに使用できるかどうか疑問に思っていました。ここで

は、作業元です:

std::unordered_map<string const, int, [](string const& key) ->size_t {return key[0];}> m = {{ "a", 1 }}; 

次のエラーで失敗しました:ここ

struct hf 
{ 
    size_t operator()(string const& key) const 
    { 
    return key[0]; // some bogus simplistic hash. :) 
    } 
} 

std::unordered_map<string const, int, hf> m = {{ "a", 1 }}; 

は私の試みだ

エラーを考える
exec.cpp: In lambda function: 
exec.cpp:44:77: error: ‘key’ cannot appear in a constant-expression 
exec.cpp:44:82: error: an array reference cannot appear in a constant-expression 
exec.cpp: At global scope: 
exec.cpp:44:86: error: template argument 3 is invalid 
exec.cpp:44:90: error: invalid type in declaration before ‘=’ token 
exec.cpp:44:102: error: braces around scalar initializer for type ‘int’ 

、それはように思わlambaはファンクタとは十分に異なり、定数式ではありません。あれは正しいですか?

+2

'std :: hash'は' std :: string'に特化していますので、ハッシュを改善/変更したくない場合は、自分で用意する必要はありません。また、あなたがやっていることを考えてみてください。 'std :: unordered_map'はテンプレート引数として*型*を期待しています。ラムダ式はまさにその式です。 – Xeo

+0

私はg ++コンパイラで(v4.5.3と-std = gnu ++ 0x)を使用していたことがわかりました。文字列キーを使用するときにハッシュ関数を指定しなかった場合、エラーが発生します。 – Adrian

+0

それは表現で、ええ、それは答えになると思います。 – Adrian

答えて

12

ラムダ関数を渡す方法は次のとおりです。

auto hf = [](string const& key)->size_t { return key[0]; }; 

unordered_map<string const, int, decltype(hf)> m (1, hf); 
           ^^^^^^^^^^^^  ^^ 
           passing type  object 

decltype(hf)の出力は、(それが=deleteによって削除されます)デフォルトコンストラクタを持たないクラス型です。したがって、λオブジェクトを構築するには、unordered_mapのコンストラクタでオブジェクトを渡す必要があります。

+1

@MM。、このように: 'std :: unordered_map m(1、hf);'。最初の引数は最初のバケットカウントで、2番目の引数はハッシャーです。悲しいことに、中括弧初期設定を使用することはできません。 – avakar

+0

興味深いですが、ラムダ関数をテンプレートパラメータとして渡すだけではないのでちょっとした詐欺です。実際には、テンプレートパラメータはヘルパーテンプレート関数を介して一緒に避けることができます: 'template auto make_unordered_map(size_t bucketCount、HASHER const&hf) - > unordered_map {戻り値unordered_map (bucketCount、hf); } 'ここに見られるように[ここ](http://ideone.com/62heUn)。それでも、面白いです。 :) – Adrian

関連する問題