Home > database >  Is there an objective reason why the explicitly instantiated std::less, std::greater and similar off
Is there an objective reason why the explicitly instantiated std::less, std::greater and similar off

Time:11-17

Stateless lambdas can be converted to function pointers, e.g. this is valid,

using Fun = bool(*)(int, int);
constexpr auto less = [](int a, int b){ return a < b; };
Fun f{less};

but objects like std::less<int>{} can't.

I do understand why std::less<>{} can't, because it's operator() is not instantiated until the object is applied to some arguments, so how could it be converted to a Fun, if the decision of what its template argument(s) are is not been taken yet?

But std::less<int>{} seems just the same as the lambda I've written above, no?

CodePudding user response:

std::less<int> has a non-static member function (operator()) that takes two ints and returns a bool.

It can be converted to a function pointer bool (*)(const std::less<int> *, const int &, const int &). (or to a pointer to member function)

If it had been defined as a static member function, then the conversion would to bool (*) (const int &, const int &) would be valid.

CodePudding user response:

Stateless lambdas can be converted to function pointers, e.g. this is valid, [...] but objects like std::less<int>{} can't.

"Can't" is the wrong word. After all, a "stateless lambda" is just an object, and it doesn't have any magical rules compared to other objects. A lambda is a class type like any other. It is simply generated by the compiler. You can hand write a type that does anything a lambda does; it'd just take more code.

The ability of stateless lambdas to be converted to function pointers is similarly not magic. Any type can have conversion operators defined for it, allowing them to be implicitly convertible to arbitrary types. For a stateless lambda, the compiler simply generates a conversion operator to a pointer to an appropriate function pointer signature.

std::less<T> could have an operator bool (*)(T const&, T const&)() const overload that returns a pointer to a function that does this comparison. But it doesn't. There's nothing stopping it from doing this, save the fact that the C standard doesn't say that the type shall have such an interface.

And this hasn't happened because nobody has proposed it for standardization.

  • Related