2013-10-15 6 views
3

게으른 평가 버전의 std :: pair.first가 필요합니다. 나의 접근 방식은, 부스트 :: 피닉스를 사용하는 템플릿 기반 함수를 정의하고 folows로 BOOST_PHOENIX_ADAPT_FUNCTION의 매크로를 사용하는 것입니다BOOST_PHOENIX_ADAPT_FUNCTION (...) 템플릿 화 된 컨테이너에서 템플릿 함수 사용

내 경우 T1에서 (내가 현재 프로그램에 필요한 특정 사건에 대한 괜찮
template <typename T1, typename T2> 
T1 first_impl(std::pair<T1,T2> p){ 
    return p.first; 
} 
BOOST_PHOENIX_ADAPT_FUNCTION(std::string, first, first_impl, 1); 

= 표준 : : 문자열). 하지만 어떻게 first_impl 함수 템플릿의 결과 유형 T1을 사용하여 미래의 사용을 위해 훨씬 더 추상화 할 수 있습니까? The documentation은 함수의 반환 형식을 첫 번째 인수의 형식으로 정의하기 위해 makro의 첫 번째 인수로 typename remove_reference<A0>::type을 사용하는 것에 대해 언급합니다. 나를 위해 작동하지 않는 것 액세스 std::pair<T1, T2>::first_type하려고

BOOST_PHOENIX_ADAPT_FUNCTION(typename A0::first_type, first, first_impl, 1); 

:이를 바탕으로 내가 좋아하는 여러 버전을 시도했다.

가 Additionaly 내가 std::remove_reference 이런 다루는 무엇 적응하기 위해 노력

template <typename T1, typename T2> first_type < std::pair<T1,T2> > 
{ typedef T1 type; } 

을 다음 그러나이 중 하나가 작동하지 않는 것 같습니다. 누군가 내가 여기서 잘못하고있는 것을 지적 할 수 있습니까?

답변

3

난 당신이 거의 first_type로했다 실제로처럼 특성을 건의 할 것입니다 :

namespace detail // by convention, hide details from enclosing namespace 
{ 
    template <typename Pair, typename First = typename std::remove_reference<Pair>::type::first_type> 
    struct first_type { 
     typedef First type; 
    }; 

// Now you can use the trait in your `first_impl` return type: 

    template <typename Pair> 
    typename first_type<Pair>::type first_impl(Pair const& p){ 
     return p.first; 
    } 
} 

을 지금, 당신은 실제로 적응에 사용할 수 있습니다

BOOST_PHOENIX_ADAPT_FUNCTION(typename detail::first_type<A0>::type, first, detail::first_impl, 1) 

완전 작동 데모 : 그것을 참조 Live on Coliru

int main() 
{ 
    using boost::phoenix::arg_names::arg1; 

    std::map<std::string, int> const m { 
     { "one", 1 }, 
     { "two", 2 }, 
     { "three", 3 }, 
     { "four", 4 } 
    }; 

    std::for_each(begin(m), end(m), std::cout << first(arg1) << "\n"); 
} 

출력

four 
one 
three 
two 
+0

고맙습니다. 나는 여전히 템플릿/특성으로 이러한 문제를 해결하는 방법에 대해 더 자세히 알아야합니다. – Dirk

+0

추가 정보 : Phoenix가 멤버 템플릿 함수'operator()'를 명시 적으로 인스턴스화하는 특정 방식으로 인해 문제가되었을 수 있습니다. 나는 명시 적으로 1 (단일) 템플릿 인자 ('pair')를 전달한다고 생각하는데, 왜 당신의 메소드 템플릿 (2 개의 인자를 요구한다)에서 작동하지 않는지 설명한다. 나는 '수영 업스트림'을 보통 좋아하지 않기 때문에 조사를하지 않았다. 나는 단지 내가 일하는 것을 알 수있는 길을 택한다. (희망적으로 나는 보통 가장 적은 저항의 길을 알고있다. :)) – sehe