2013-05-26 3 views
13

std :: unordered_map을보고 있었는데 문자열을 키로 사용하고 싶다면 펑터가 포함 된 클래스를 만들어야한다는 것을 알았습니다.템플릿 매개 변수에 람다 함수를 사용할 수 있습니까?

호기심에서 람다를 사용할 수 있는지 궁금합니다. 여기

는 작업 원의 : 다음 오류로 실패

std::unordered_map<string const, int, [](string const& key) ->size_t {return key[0];}> 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’ 

오류 감안할 때, 그것은이 있음을 보일 수있을 것입니다 여기에

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 }}; 

내 시도이다 lamba는 functor와 충분히 다르므로 상수 표현이 아닙니다. 그 맞습니까?

+2

'std :: hash'는'std :: string'에 특화되어 있습니다. 해시를 향상 시키거나 변경하고 싶지 않으면 무언가를 제공 할 필요가 없습니다. 또한, 당신이하고있는 일에 대해서 생각 해보자.'std :: unordered_map'은 템플릿 인자로 * type *을 기대하며, 람다 식은 정확히 표현식, 즉 * 값이 아닌 * 형식이다. – Xeo

+0

g ++ 컴파일러에서 (v4.5.3 with -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);'. 첫 번째 인수는 초기 버킷 수이고 두 번째 인수는 해시입니다. 슬프게도이 경우 중괄호 초기화를 사용할 수 없습니다. – avakar

+0

흥미 롭습니다. 다만 람다 함수를 템플릿 매개 변수로 전달하는 것이 아니기 때문에 다소 치욕적입니다. 사실, 템플릿 매개 변수는 도우미 템플릿 함수를 통해 함께 피할 수 있습니다 :'template auto make_unordered_map (size_t bucketCount, HASHER const & hf) -> unordered_map { return unordered_map (bucketCount, hf); }'(여기에서 볼 수 있듯이) (http://ideone.com/62heUn). 여전히 흥미 롭습니다. :) – Adrian

관련 문제