The process of determining the function to call based on the arguments is called overload resolution, and the standard lists in which cases it gets used:
13.3 Overload resolution [over.match]
2 Overload resolution selects the function to call in seven distinct contexts within the language:
(2.1) -- invocation of a function named in the function call syntax (13.3.1.1.1);
(2.2) -- invocation of a function call operator, a pointer-to-function conversion function, a reference-to-pointer-to-function conversion function, or a reference-to-function conversion function on a class object named
in the function call syntax (13.3.1.1.2);
(2.3) -- invocation of the operator referenced in an expression (13.3.1.2);
(2.4) -- invocation of a constructor for direct-initialization (8.5) of a class object (13.3.1.3);
(2.5) -- invocation of a user-defined conversion for copy-initialization (8.5) of a class object (13.3.1.4);
(2.6) -- invocation of a conversion function for initialization of an object of a nonclass type from an expression of class type (13.3.1.5); and
(2.7) -- invocation of a conversion function for conversion to a glvalue or class prvalue to which a reference (8.5.3) will be directly bound (13.3.1.6).
Of these, the only one that applies to regular functions is 2.1, and that requires a f(args)
context which only tells the caller the result.
So, what you ask for cannot be done. Not exactly, anyway.
Now, depending on what you want to accomplish, there are some things that are possible:
It is possible to get a pointer to the function if you know the exact signature: given template <typename T> int hello(A<T> a, A<T> b)
, you can obtain the address using that: static_cast<int(*)(A<int>,A<int>)>(hello)
. However, for this to work, you need to know the return type (which you might be able to obtain using decltype
), and you need to know the parameter types (which may be different from the argument types, and which you aren't able to obtain reliably).
It is also possible to get a pointer to a function that, when called, will have the same effect as hello
:
auto callable = +[](A<int> a, A<int> b) { return hello(a, b); };
The [](A<int> a, A<int> b) { return hello(a, b); }
creates a lambda without any captures, and lambdas without any captures can implicitly be converted to a function pointer of a matching type. The +
forces the use of that conversion, without requiring the type to be spelled out.
However, this will not have the same address as hello
, so might not be suitable for subsequent comparisons.
That's the best you can get.