beginners question on unary_function<>

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • jabbah
    New Member
    • Nov 2007
    • 63

    beginners question on unary_function<>

    Hi,

    im failing with my first try to use unary_function, i got something (which i partly borrowed from another forum):

    Code:
    #include <algorithm>
    #include <functional>
    #include <iostream>
    using namespace std;
    template <typename T> class is_good : public std::unary_function<T, bool> { 
    public:
    	is_good(const T & arg) : _val(arg) { }
    	~is_good() { }
    	bool operator()(const T p) const {
    		return p == _val;
    	}
    private:
    	T _val;
    };
    //int doit ( 
    //	const int* a, 
    //	unsigned int size,
    //	std::unary_function< int, bool > condition ) 
    //{
    //	int sum = 0;
    //	for ( unsigned int i =0 ; i < size; ++i )
    //	{
    //		if ( condition(a[i]) )
    //			sum += a[i];
    //	}
    //	return sum;
    //}
    
    
    void main()
    {
    	int a[10] = {4, 9, 5, 6, 9, 10, 9, 255, 60, 0};
    	int* x = std::find_if(a, a+10, is_good<int>(10));
    	//doit( a, 10, is_good<int>(12) );
    }
    which works, but when i comment in the 'doit' part the compiler complains, that condition(a[i]) does not evaluate to a function ....

    i suppose its a trivial error?! anybody?
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    std::unary_func tion< int, bool > is not a predicate, that is there is no member defined in unary_function

    std::unary_func tion< int, bool >::operator()(. ..);

    so a variable of that type can not be used in a call

    condition(...)

    Comment

    • jabbah
      New Member
      • Nov 2007
      • 63

      #3
      alright!
      thanks. of course

      so now i do:
      Code:
      template< typename PREDICATE >
      int doit ( 
      	const int* a, 
      	unsigned int size,
      	PREDICATE predicate ) 
      {
      	int sum = 0;
      	for ( unsigned int i =0 ; i < size; ++i )
      	{
      		if ( predicate(a[i]) )
      			sum += a[i];
      	}
      	return sum;
      }
      which does what i want. thanks banfa

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        I just wanted to be sure everyone knows the STL-speak for these terms:

        1) Generator.
        A function that takes no arguments.

        2) unary function
        A function that takes one argument.

        If this function returns a bool is is called a predicate.

        3) binary function
        A function that takes two arguments.

        If this function returns a bool it is called a binary predicate.


        So you have to be careful reading STL documentation. All you will see, for example, is the word predicate. It is assumed you know this to be a unary function that returns a bool.

        Also be aware that there are classes named unary_function and binary_function that are to help you in writing adaptable functors and function adapters:

        Code:
        template<class T>
        class Y : public unary_function<T,T>
        {
        
        };
        
        template<class T>
        class Z : public binary_function<T,T,T>
        {
        
        };
        These adaprtable functors and function adapters are needed since STL supports only zero, one or two arguments. If you need more, then you write an adaptable functor.

        Comment

        • jabbah
          New Member
          • Nov 2007
          • 63

          #5
          speaking of terminology, i notice that you emphasise the terms "adaptable functors" and "function adapters". whats behind that?

          my guess is
          - functor is a class with an operator()
          - its called adaptable, if its derived from std::unary_func tion (or binary), ie has typedefs for args and returntypes

          correct me if im wrong. and whats a function adapter?

          Comment

          • weaknessforcats
            Recognized Expert Expert
            • Mar 2007
            • 9214

            #6
            binder1st is a function adapter.

            That is, a function adapter is a class that assumes the existence of the typdefs for result_type, first_argument_ type and second_argument _type.

            If you have an adaptable function, you can use a function adapter to reduce the number of arguments in the adapable function. Like with multiplies. This is a binary function but you can use it as a unary function if you first create a function adapter object that contains one of the multiplies arguments as member data. The operator() of the function adapter object need only to have one argument (a unary function) since the other argument can be obtained from the function adapter member data. In this way you can multiply using a function with only one arguiment.

            Comment

            • jabbah
              New Member
              • Nov 2007
              • 63

              #7
              interessting.

              thanks.

              Comment

              Working...