9

With my compiler

typedef const double&(*fT)(const double&, const double&);
typedef std::function<const double&(const double&, const double&)> std_func;

fT f1 = std::max<double>;                            //(1)
std_func f2 = static_cast<fT>(std::max<double>);     //(2)
std_func f3 = f1;                                    //(3) 

(1, 2, 3) work but

auto f4 = std::max<double>;                          //(4)
std_func f5 = std::max<double>;                      //(5) 

(4, 5) don't. The compiler complains about its incapability to choose the overload for case 5.

Is this behavior normal?

What is the most portable and correct way to write it?

jimifiki
  • 5,377
  • 2
  • 34
  • 60
  • 1
    What are you trying to achieve? – Slava May 29 '18 at 14:27
  • @Slava I'm trying to fix the compiling errors of an old code base on one more compiler. The old code was (5). I fixed it by writing (3). Thx for your commen, an answer is welcome :-) – jimifiki May 29 '18 at 14:32
  • I think then you should rephrase your question as how to make (5) compile and what variants you tried, as it is written it is not clear at all – Slava May 29 '18 at 14:39

1 Answers1

12

There are two possible overloads of instantiation of std::max<double>: std::max(double, double) and std::max(std::initializer_list<double>). Because of that, versions 4 and 5 fail, since it can't figure out which overload matches.

Cases 1, 2 and 3 succeed because of the special rules - when taking an address of overload function, type of the result is used to select the proper overload.

SergeyA
  • 61,605
  • 5
  • 78
  • 137