Need Help to find the error

I have below code, for functor.
But this is giving compilation error in VS17.

#include <iostream>
#include <functional>
template <typename T>
struct less : public std::unary_function <T, bool>
{
bool operator () (T& rhs, T& lhs)
{
return rhs > lhs ? true : false;
}
};

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

At if (less<int>(a,b)), it is giving error.
std::unary_function was removed in C++17.

Do you want something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

template <typename T>
struct les {
	bool operator () (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;
}

Last edited on
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.)
Now I understand, the problem. Yes thanks to both of you for the clarification.
Topic archived. No new replies allowed.