Why have unary_function, binary_function been removed from C++11?
Asked Answered
C

2

19

I found that binary_function is removed from C++11. I am wondering why.

C++98:

template <class T> struct less : binary_function <T,T,bool> {
  bool operator() (const T& x, const T& y) const {return x<y;}
};

C++11:

template <class T> struct less {
  bool operator() (const T& x, const T& y) const {return x<y;}
  typedef T first_argument_type;
  typedef T second_argument_type;
  typedef bool result_type;
};

MODIFIED----------------------------------------------------------------------------

template<class arg,class result>
struct unary_function
{
       typedef arg argument_type;
       typedef result result_type;
};

For example, if we want to write our adapter for function even in C++98,

template <class T> struct even : unary_function <T,bool> {
  bool operator() (const T& x) const {return 0==x%2;}
};

find_if(bgn,end,even<int>()); //find even number

//adapter
template<typename adaptableFunction >
class unary_negate
{
   private:
       adaptableFunction fun_;
   public:
       typedef adaptableFunction::argument_type argument_type;

       typedef adaptableFunction::result_type result_type;  
       unary_negate(const adaptableFunction &f):fun_(f){}

       bool operator()(const argument_type&x) 
       {
           return !fun(x);
       }
}

find_if(bgn,end, unary_negate< even<int> >(even<int>()) ); //find odd number

How can we improve this in C++11 without unary_function?

Cosimo answered 13/3, 2014 at 17:51 Comment(0)
H
23

It isn't removed, it's just deprecated in C++11. It's still part of the C++11 standard. You can still use it in your own code. It was removed in C++17 though.

It isn't used in the standard any more because requiring implementations to derive from binary_function is over-specification.

Users should not care whether less derives from binary_function, they only need to care that it defines first_argument_type, second_argument_type and result_type. It should be up to the implementation how it provides those typedefs.

Forcing the implementation to derive from a specific type means that users might start relying on that derivation, which makes no sense and is not useful.

Edit

How can we improve this in c++11 without unary_function?

You don't need it.

template<typename adaptableFunction>
class unary_negate
{
   private:
       adaptableFunction fun_;
   public:
       unary_negate(const adaptableFunction& f):fun_(f){}

       template<typename T>
           auto operator()(const T& x)  -> decltype(!fun_(x))
           {
               return !fun_(x);
           }
}

In fact you can do even better, see not_fn: a generalized negator

Hest answered 13/3, 2014 at 18:32 Comment(0)
M
22

With variadic templates, a lot of general function composing can be expressed much more simply and consistently, so all of the old cruft is no longer necessary:

Do use:

  • std::function
  • std::bind
  • std::mem_fn
  • std::result_of
  • lambdas

Don't use:

  • std::unary_function, std::binary_function
  • std::mem_fun
  • std::bind1st, std::bind2nd
Mavilia answered 13/3, 2014 at 17:57 Comment(10)
binary_function <T,T,bool> can simplify our work and make code more consistent, right?Cosimo
@camino: Can it, though?Mavilia
without it we need define typedef T first_argument_type;.... , maybe we will forgot somethingCosimo
@camino: Do we though? Why not use the existing std::function::first_argument_type?Mavilia
so less<T> in c++11 define first_argument_type,second_argument_type,result_type is only to be compatible with c++98, right?Cosimo
@camino: Wait, less<T> doesn't define it, but std::function defines it for one- and two-argument specializations. But you don't generally need those types when you have arbitrary binding facilities available anyway...Mavilia
@KerrekSB, less<T> does define them (to be compatible with C++98), less<void> doesn'tHest
FYIW std::function::first_argument_type seems also to be deprecated in C++17 en.cppreference.com/w/cpp/utility/functional/functionFirsthand
@bergercookie: What is "FYIW"?!Mavilia
@KerrekSB A typo (FWIW), probably.Anastigmat

© 2022 - 2024 — McMap. All rights reserved.