문제

나는 C ++의 Functors와 함께 놀았습니다. 특히, 나는 쌍의 첫 번째 요소로 정렬하고 싶은 쌍의 쌍을 가지고 있습니다. 나는 완전히 전문화 된 기능을 작성하기 시작했습니다 (즉, "bool myless than (mypair & lhs, mypair & rhs)"과 같은 것). 그런 다음 이런 종류의 것들이 흥미로워서 일반적인 "이 쌍의 첫 번째 요소에 적용 f"functor를 작성하려고했습니다. 아래를 썼지 만 G ++는 그것을 좋아하지 않습니다. 나는 얻다:

오류 : 'Template struct pair1stfunc2'에 대한 템플릿 매개 변수 목록에서 인수 2에서 유형/값 불일치 '오류 : 예상 유형,'Less '가 있습니다.

#include <algorithm>
#include <functional>
#include <utility>
#include <vector>

template <class P, class F>
struct Pair1stFunc2
{
    typename F::result_type operator()(P &lhs, P &rhs) const
    { return F(lhs.first, rhs.first); }

    typename F::result_type operator()(const P &lhs, const P &rhs) const
    { return F(lhs.first, rhs.first); }
};

typedef std::pair<int,int> MyPair;
typedef std::vector<MyPair> MyPairList;

MyPairList pairs;

void foo(void)
{
    std::sort(pairs.begin(),
              pairs.end(),
              Pair1stFunc2<MyPair, std::less>());
}

누구든지 내가 여기서 잘못하고있는 일에 대해 빛을 발할 수 있습니까? 나는 이것이 약간 인공적인 예라는 것을 알고 있지만, STL-FU를 개선하기 위해서만 무슨 일이 일어나고 있는지 알고 싶습니다.

도움이 되었습니까?

해결책

사용중인 비교 유형을 사용하여 std ::를 전문화해야합니다.

Pair1stFunc2<MyPair, std::less<int> >()

트릭을 할 것입니다. 자신의 Operator () 내에서 클래스를 직접 호출 할 수 없으므로 비교 유형의 객체를 인스턴스화해야합니다. 예 : 변화

return F(lhs.first, rhs.first);

에게

F func;
return func(lhs.first, rhs.first);

또 다른 대답에서 알 수 있듯이 전문화를 펀치로 옮길 수도 있습니다.

다른 팁

Dirkgently의 답변을 확장하려면 다음은 의도 한대로 작동 할 수있는 예가 있습니다.

template <typename T, template <typename> class F>
struct Pair1stFunc2
{
    template <typename P>
    typename F<T>::result_type operator()(P &lhs, P &rhs) const
    { F<T> f; return f(lhs.first, rhs.first); }

    template <typename P>
    typename F<T>::result_type operator()(const P &lhs, const P &rhs) const
    { F<T> f; return f(lhs.first, rhs.first); }
};

void foo(void)
{
    std::sort(pairs.begin(),
              pairs.end(),
              Pair1stFunc2<int, std::less>());
}

그것이 작동하지만 정확히 당신이 생각한 것이 아닐 수도 있습니다.

주목하십시오 std::less 그 자체가 템플릿이며 템플릿 템플릿 매개 변수를 호출 할 때 템플릿 템플릿 매개 변수를 지정하지 않습니다. foo() 기능 sort! 여기 less 불완전한 유형이므로 문제입니다.

Unkesen과 유사합니다. 그러나 템플릿 템플릿을 사용할 필요는 없습니다.

#include <algorithm>
#include <functional>
#include <memory>
#include <vector>

typedef std::pair<int,int> MyPair;
typedef std::vector<MyPair> MyPairList;
MyPairList pairs;


// Same as original.
template <typename T,typename F>
struct Pair1stFunc2
{
    template <typename P>
    typename F::result_type operator()(P &lhs, P &rhs) const
    { F f;  // Just need to create an anstance of the functor to use.
      return f(lhs.first, rhs.first); }

    template <typename P>
    typename F::result_type operator()(const P &lhs, const P &rhs) const
    { F f;  // Just need to create an anstance of the functor to use.
      return f(lhs.first, rhs.first); }
};


void foo(void)
{
    std::sort(pairs.begin(),
              pairs.end(),
              Pair1stFunc2<int, std::less<int> >()); // initialize the version of less
}

가장 간단한 해결책은 당신이 원하는 것을 인수로 말하고 적절한 서명을 가진 기능을 말하는 것입니다.

template<typename P, bool (*F)(P,P)> struct Pair1stFunc2 { ... }

이 경우, 두 번째 인수로 함수 템플릿을 전달하면 인수 유형으로 p, p로 과부하 해결이 수행됩니다. 과부하 해상도를 struct Pair1stFunc2::operator()

당신은 또한 a를 통과 할 가능성을 원합니다 untctor, 그러나 그 사람들은 템플릿 유형 인수로 전달 된 다음 OPERATOR () 내에서 만들어 져야합니다.

typename F::result_type operator()(const P &lhs, const P &rhs) const
{ return F()(lhs.first, rhs.first); }

여기서 F는 functor 유형이고 f () 해당 functor의 인스턴스입니다.

세 번째 사례는 이미 앞서 다루어졌습니다. Functor 템플릿. STD :: 덜 템플릿입니다. 이 경우 템플릿 템플릿 인수가 필요합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top