2016-10-20 3 views
2

이 반복자의 값을 비교하기 위해 두 개의 반복자와 사용자 지정 비교기를 사용하는 함수가 필요합니다. 나는 이것을 위해 추가적인 템플릿 인자를 사용하고 싶지 않다.어떻게 제대로 다른 템플릿 함수에 비교자를 전달하십시오.

template<typename T> 
void foo(T begin, T end, 
    function<bool(decltype(*begin), decltype(*begin))> compare = less<decltype(*begin)>()) 
{ 
    // I want to use 'compare' as: "compare(*begin, *begin);" 
} 

이 코드는 그 소리에 의해 일반적으로 컴파일되었지만, GCC 5.4.0에 나는 약간의 오류가있어 : 나는이 방법으로 그것을 구현 한이 코드를 수정하는 방법

binary_heap.cpp:10:79: error: local variable 'begin' may not appear in this context 
    function<bool(decltype(*begin), decltype(*begin))> compare = less<decltype(*begin)>()) 
                      ^
binary_heap.cpp:10:85: error: template argument 1 is invalid 
    function<bool(decltype(*begin), decltype(*begin))> compare = less<decltype(*begin)>()) 
을 그래서 그것은 clang과 GCC에서 성공적으로 컴파일 될 수 있습니까? 아니면 그러한 기능을 정의하기에 더 적합한 솔루션이 있습니까?

+0

왜이 경우에 추가 템플릿 인수를 사용하지 않으시겠습니까? – Yakk

답변

5

평범하지 않은 컨텍스트에서도 (기본 설정을 수정하여 해당 제한을 완화해야하지만) 기본 매개 변수에는 매개 변수를 사용할 수 없습니다. 대신 decltype(*begin)의 사용

decltype(*std::declval<T&>()) 

편집 : 아마도 * 연산자를 적용하는 좌변 값을 산출하는 경우, 다음 decltype 지정이 좌변 참조를 해결할 수 있기 때문에 당신이 원하는 일을하지 않는 사실,하지만, 참조되지 않는 유형이 std::less의 인수가되기를 원할 것입니다. 더 나은 사용하기 :

typename std::iterator_traits<T>::value_type 

편집 2 : 나는 krzaq에 동의, 그것은 또 다른 템플릿 매개 변수를 추가하는 것이 좋습니다.

4

function (자세한 내용은 here)의 사용을 강요함으로써 알고리즘 성능을 크게 향상시킬 수 있습니다. 그냥 템플릿 Compare을 추론하고 황금있어 가지고 :

template<typename T, typename Compare = std::less<typename iterator_traits<T>::value_type>> 
void foo(T begin, T end, Compare compare = {}) 
{ 
    // I want to use 'compare' as: "compare(*begin, *begin);" 
} 

는 흥미롭게도, 표준 알고리즘의 힘/대신 전달 참조의 값을 취함으로써 경량 펑터의 사용을 권장합니다. 당신이 std::less<void>std::less<>, 기본값을 사용하여 실제 비교를하고 operator() 템플릿있다 :


실제 질문에 대답하려면

template<typename T> 
void foo(T begin, T end, 
    function<bool(decltype(*begin), decltype(*begin))> compare = less<>()) 
{ 
    // I want to use 'compare' as: "compare(*begin, *begin);" 
} 
+0

호기심에서 벗어나'function'을 사용하여 어떤 방법으로 성능을 비관적으로합니까? – RyanP

+1

@RyanP 님이 답변을 편집했습니다 – krzaq

+0

@krzaq 고맙습니다! 최상의 성능에 관심이 있다면 어떤 솔루션을 선택해야합니까? – 0x1337

3

다른 템플릿 매개 변수 Compare를 추가합니다. 이렇게하면 컴파일러에서 인라인을 쉽게 만들 수 있습니다. 내가 센티넬을 지원하는 동안.위의 금지, C++ (14) 가정

그러나
template<class It, class Sentinel, class Compare=std::less<void>> 
void foo(It begin, Sentinel end, Compare cmp={}) { 
} 

, 나는이 작업을 수행 할 것 :

template<class T> 
using comparator_sig = bool(T const&,T const&); 
template<class T> 
using comparator = std::function<comparator_sig<T>>; 
template<class It> 
using compare_inside_it = comparator< 
    typename std::iterator_traits<It>::value_type 
>; 

template<typename T> 
void foo(T begin, T end, compare_inside_it<T> compare = less<>) { 
} 

를 C++ 11에 나는 쓴다 내 자신의 less<void> :

struct compare_less { 
    template<class T> 
    bool operator()(T const& lhs, T const& rhs) const { 
    return std::less<T>{}(lhs, rhs); 
    } 
}; 

및 do :

template<typename T> 
void foo(T begin, T end, compare_inside_it<T> compare = compare_less{}) { 
} 

또는 j 해야 할 일 :

template<typename T> 
void foo(T begin, T end, compare_inside_it<T> compare = {}) { 
    if (!compare) compare=compare_less{}; 
} 
관련 문제