c++type-conversionc++17function-pointersfunction-object

Is there an objective reason why the explicitly instantiated std::less, std::greater and similar offer no conversion to function pointer?


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?


Solution

  • 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.