int main()
{
int a = 5;
int b = 6;
if (less<int>(a,b))
{
std::cout << a << "is less than" << b << std::endl;
}
else
std::cout << b << "is less than" << a << std::endl;
}
#include <iostream>
template <typename T>
struct les {
booloperator () (const T& lhs, const T& rhs) const {
return lhs < rhs;
}
};
int main() {
int a = 5;
int b = 6;
if (les<int>{}(a, b)) {
std::cout << a << " is less than " << b << std::endl;
} else
std::cout << b << " is less than " << a << std::endl;
}
That is not an unary function to begin with; yields effectively same errors with C++98 and C++20:
main.cpp:17:8: error: no matching constructor for initialization of 'les<int>'
if ( les<int>(a,b) )
^ ~~~
main.cpp:5:8: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided
struct les : public std::unary_function <T, bool>
^
main.cpp:5:8: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 2 were provided
main.cpp:17:8: error: value of type 'les<int>' is not contextually convertible to 'bool'
if ( les<int>(a,b) )
^~~~~~~~~~~~~
2 errors generated.
unary_function does not define operator(); it is expected that derived classes will define this. unary_function provides only two types - argument_type and result_type - defined by the template parameters.
Some standard library function object adaptors, such as std::not1, require the function objects they adapt to have certain types defined; std::not1 requires the function object being adapted to have a type named argument_type. Deriving function objects that take one argument from unary_function is an easy way to make them compatible with those adaptors.
The now removed std::binary_function would be more logical, but does yield essentially the same errors.
The real issue is in the less<int>(a, b).
It tries to construct an unnamed temporary object of type less<int> and passes two parameters a, b to the constructor.
There is no such constructor.
When unary_function and binary_function were used, the ebject was constructed and passed to algorithm: less<int>().
The algorithms did then call the objects with one or two parameters, respectively.
The les<int>{}(a, b) is ok, because it first constructs an unnamed temporary object with les<int>{} and then calls the operator() of that object with those two parameters. (The older syntax les<int>()(a, b) was ok too.)