2015-01-08 3 views
9

다음 프로그램은 불법이며, 이해하고 싶은 이유 :std :: 함수를 사용하는이 함수에 람다를 전달할 수없는 이유는 무엇입니까?

#include <functional> 
#include <iostream> 

template<typename Result, typename Arg> 
void deduce(std::function<Result(Arg)> f) 
{ 
    std::cout << "Result: " << typeid(Result).name() << std::endl; 
    std::cout << "Arg: " << typeid(Arg).name() << std::endl; 
} 


int main() 
{ 
    auto f = [](int x) 
    { 
    return x + 1; 
    }; 

    deduce(f); 

    return 0; 
} 

clang의 출력 :

$ clang -std=c++11 test.cpp 
test.cpp:48:3: error: no matching function for call to 'deduce' 
    deduce(f); 
    ^~~~~~ 
test.cpp:26:6: note: candidate template ignored: could not match 'function<type-parameter-0-1 (type-parameter-0-0)>' against '<lambda at test.cpp:34:13>' 
void deduce(std::function<T2(T1)> f) 
    ^
1 error generated. 

그것은 내가 std::function 내 람다를 변환 할 수 에게서는처럼 보인다 접수는 deduce입니다. 이 경우 컴파일러가 적절한 변환을 적용 할 수없는 이유는 무엇입니까?

답변

5

문제는 int을 소요하고 int를 반환하는 람다 std::function<int(int)>으로을 변환 할 수 있지만, 그 형태가 하지std::function<int(int)>하지만, 임의의 구현 정의 유형은 내가 생각하는 것입니다.

컴파일러에게 원하는 형식을 알려줌으로써이 문제를 해결할 수 있습니다. 그런 다음 예상대로 변환이 수행됩니다.

auto f = [](int x){ return x + 1; }; 
deduce<int, int>(f); // now ok 

또는 정적 유형 f을 명시해야합니다.

std::function<int(int)> f = [](int x){ return x + 1; }; 
deduce(f); // now also ok 
+0

감사합니다. 형식이 동일하지 않다는 것을 이해하지만 컴파일러가 여기에 적절한 변환을 적용 할 수없는 이유를 이해하려고합니다. –

+2

문제는 인수 값의 변환이 아니라 템플릿 매개 변수의 공제입니다. 일단 내가 알았다면 (내가 준 첫 번째 발췌 문장 에서처럼), 변환은 괜찮습니다. 내가 여기에 적용되는 정확한 규칙을 찾을 수 있는지 여부를 시험해 보겠습니다. – 5gon12eder

+1

예, 공제가 문제입니다. 그렇지 않으면 모든 것이 이루어지기 때문에 정확하게 공제 할 수 있습니다. 모든 전문화 과정에서 필요한 변환을 할 수도 있고하지 않을 수도 있습니다. – Deduplicator

관련 문제