2017-12-04 4 views
2

템플릿 함수에 템플릿 매개 변수로 std::max 함수를 전달하려고하지만 컴파일러가 함수 유형을 추론 할 수없는 오류를 인쇄합니다. 간단한 예제가 동일한 문제를 재현합니다. 그것은 자신의 max2 기능을 작동하지만 STL std::max 작동하지 않습니다 here와 같이std :: max 함수 포인터를 저장할 자동 변수

#include <algorithm> 

template <class T> 
T max2(const T& a, const T& b) { return std::max(a, b); } 

int main() { 
#if 1 
    auto f = max2<float>; 
#else 
    // error: unable to deduce ‘auto’ from ‘max<float>’ 
    auto f = std::max<float>; 
#endif 
    float max_val = f(1.0f, 2.0f); 
    return 0; 
} 
+1

문제는 [여러'표준 : :가 max']이다 (http://en.cppreference.com/w/cpp/algorithm/max)와 컴파일러는 알고하지 않는 한 당신을 필요. –

+1

필자는 (비 템플릿) 클래스를 생성하고 템플릿 함수 호출 연산자 (아마도 다른 시그니처가 하나 이상인)를 제공하고 그 클래스의 객체를 전달하는 템플릿 함수의 스타일을 개인적으로 선호합니다. 그런 다음 템플릿 매개 변수를 지정하지 않아도됩니다. 'max '대신에'max'를 넘겨 줄 수 있습니다. 또는 더 나쁜 경우, 여러 가지 자유 함수 오버로드가있을 때 불필요한 정적 캐스트가 필요합니다. [range-v3] (https://github.com/ericniebler/range-v3) 라이브러리는 모든 기능에 대해이 작업을 수행합니다. –

답변

4

, std::max<float>는 하나의 명백한 함수가 아닙니다. 지금부터, 과부하 세트이고 두 가지 가능성이 여전히있다 :

constexpr const float& max(const float& a, const float& b); 
constexpr float max(std::initializer_list<float> ilist); 

당신은 두 가지 옵션이 있습니다 적절한 유형에

  1. 주연 :

    auto f = static_cast<const float&(*)(const float&, const float&)>(std::max); 
    
  2. 랩 그것에서 람다 :

    auto f = [](float a, float b) { return std::max(a, b); }; 
    // Note there's no by-reference behaviour in this lambda. 
    

앞으로는 더 잘 할 수있을 것으로 기대됩니다. 특히, 반영은 lift 유틸리티가 auto f = lift(reflexpr(std::max));과 같은 것을 사용할 가능성을 허용해야합니다. 매크로를 사용하여 그러한 것을 에뮬레이션 할 수 있습니다 (매크로를 람다로 확장시킴으로써 가장 간단하게 수행 할 수 있습니다). 적어도 하나의 LIFT 매크로를 보았습니다.

2

std::max에는 하나 이상의 템플릿 과부하가 있습니다. 어떤 것을 사용해야하는지 지정하려면 static_cast을 사용할 수 있습니다.

static_cast 또한 특정 유형

예에 함수 포인터에 변환을 수행하여 함수의 과부하를 명확하게하기 위해 사용될 수있다

auto f = static_cast<const float& (*)(const float&, const float&)>(std::max<float>); 
관련 문제