Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++17 template argument deduction mystery [duplicate]

In C++17 you can do this:

#include <iostream>
#include <algorithm>
#include <functional>

int main()
{
    double values[5] = { 1.1, 2.2, 3.3, 4.4, 5.5 };

    // Notice this:
    std::sort(values, values+5, std::greater());

    for(double v: values) std::cout << v << " ";
    std::cout << "\n";
}

You don't actually need to specify the template parameter of std::greater. It will be automatically deduced as double. That's really nice.

But wait... How?!?

There's nothing telling std::greater that the template parameter should be of type double. It's not taking any constructor parameters or anything. And the declaration of std::sort() is ostensibly like this:

template<class RandomIt, class Compare>
void sort(RandomIt first, RandomIt last, Compare comp);

so there's nothing there telling it that it should be double either.

So how?

like image 717
Warp Avatar asked Sep 04 '19 23:09

Warp


1 Answers

There are two different definitions for std::greater. One requires a template parameter on the type, the other does not.

You're using the second one.

This is what std::greater looks like (leaving off modifiers like constexpr and noexcept and different return types):

template <typename T = void>
struct greater
{
    bool operator () (const T& x, const T& y) { return x > y; }
};

template <>
struct greater<void>
{
    template <typename T1, typename T2>
    bool operator () (const T1& x, const T2& y) { return x > y; }
    typedef void is_transparent;
};
like image 163
Marshall Clow Avatar answered Oct 21 '22 08:10

Marshall Clow