G ++ rejects my simple functor with "expected type, got" xyz ""

I play with functors in C ++. In particular, I have a vector of pairs that I would like to sort by the first element of the pair. I started writing a fully specialized functor (for example, "bool MyLessThan (MyPair & lhs, MyPair & rhs)"). Then, simply because this material is interesting, I wanted to try writing a common functor, "Apply F to the first elements of this pair." I wrote below, but g ++ doesn't like it. I get:

error: type / value mismatch in argument 2 in the list of template parameters for 'template struct Pair1stFunc2' error: expected type, received "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.

+5
5

std:: less , .

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

. () , . .

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

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

, .

+2

dirkgently answer, , , :

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>());
}

, , , .

+6

, std::less , , foo() function sort! less , , .

+3

unesen. .

#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
}
+2

, , :

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

, P, P . , struct Pair1stFunc2::operator()

You also need the ability to pass in a functor, but they must be passed as an argument of a template type, and then created inside an operator ():

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

Here F is the type of functor, and F () is an instance of this functor.

The third case has already been considered earlier, the functor pattern. std :: less is such a template. In this case, you need the template template argument.

+1
source

All Articles