With class template argument deduction we can write:
std::less Fn;
However, G++ 8.2 rejects this code:
#include <algorithm>
#include <vector>
#include <functional>
int main()
{
std::vector v= { 1, 3, 2, 7, 5, 4 };
std::sort(v.begin(),v.end(),std::greater());
}
emitting the following error:
error: cannot deduce template arguments for 'greater' from ()
Clang++ 7.0 and MSVC 15.8.0 compile it without warnings. Which compiler is right?
Clang and MSVC are correct. This should be well-formed because of the combination effect of implicitly-generated deduction guides (since C++17) and default template argument.
(emphasis mine)
Given
std::greater()
, the implicitly-generated deduction guide is applied and the additional fictional function is selected at last. As the result of overload resolution the default argumentvoid
is applied, then the deduced type will bevoid
. That meansstd::greater()
should be same as writingstd::greater<void>()
orstd::greater<>()
.BTW: Gcc doesn't compile with
std::greater()
, butstd::greater{}
orstd::greater g;
are fine, it might be gcc's bug.GCC is wrong. There is already a bug report.
[dcl.type.simple]/2 says:
And [dcl.type.class.deduct]/2 says:
Such use is allowed.
[temp.arg]/4 describes the syntax error that a template-id is required but there is no
<>
. However herestd::greater
is not resolved as a template-id so that paragraph does not apply.