C++ 템플릿 람다함수가 인자로 전달이 안됩니다.

조회수 2331회
//
//  main.cpp
//  test
//
//  Created by bodguy on 2016. 8. 22..
//  Copyright © 2016년 bodguy. All rights reserved.
//

#include <iostream>
#include <functional>
#include <type_traits>

template<typename T, typename = std::enable_if_t<std::is_integral<T>::value || std::is_floating_point<T>::value > >
void add(T p, const std::function<bool(T,T)>& func) {
    std::cout << std::boolalpha;
    std::cout << func(p,p+1) << std::endl;
}

int main(int argc, const char * argv[]) {
    const std::function<bool(float,float)>& f = [](float a, float b){return a < b;};
    add(10.2f, f);
    // 아래거는 안되는이유??
    // add(10.2f, [](float a, float b){return a < b;});
    return 0;
}

위의 코드에서 add(10.2f, f); 는 제대로 호출이 되는데 왜 람다식을 인자로 바로 전달했을시에는 컴파일 오류가 나는 걸까요??

1 답변

  • 일단 정확히는 모르겠으나, 제 생각을 한번 적어 보겠습니다.

    문제는 타입 추론이 어려워서 발생하는 것 같습니다.

    람다를 입력하여 function을 생성 할 경우 template<typename F> function(F f) 생성 자를 사용합니다. 이 때 function 클래스 템플릿의 템플릿 인자에 맞게 호출 할 수 있는 람다를 입력할 수 있습니다.

    function<bool(float, float)>의 경우 [](double, flaot) { ... }, [](double, double) { ... } 도 입력될 수 있습니다.

    다시 말해 [](float a, float b){return a < b;} 만으로는 어떤 function 템플릿 클래스인지 추론할 수 없습니다.

    add에 입력한 첫번 째 인자인 10.2f를 통해 float으로 추론하고 두번 째 인자인 람다를 통해 타입을 추론하여 T가 동일할 경우, add<T, ...>를 인스턴스화 할 텐데 두번 째 인자로 부터 T를 추론하기 어렵기 때문에 컴파일 에러가 발생하는 것 같습니다.

    따라서 T에 대한 템플릿 인자를 아래와 같이 명시해 주면, add의 두 번째 파라미터의 타입이 추론되고 람다가 function<bool(float, flaot)> 으로 변환될 수 있기 때문에 컴파일에 성공할 수 있는 것 같습니다.

     add<float>(10.2f, [](float a, float b){return a < b;});
    

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)