是否有可能获得函数模板的隐式实例化的地址?

Jav*_*uez 11 c++ templates c++11

我想知道是否有任何方法可以获取由一组特定参数生成的函数模板的实例化地址.

#include <iostream>

template <typename T>
class A {}; 

template <typename T, typename T2>
int hello(A<T> a, A<T2> b, int c)
{
    return 69; 
}

int main()
{
    A<int> a;
    A<float> b;
    std::cout << (&hello)(a, b, 3) << "\n";                                                                                                                                                           

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

此代码打印函数调用返回的值.如何打印为a和b参数实例化的"hello"版本的地址?我希望编译器能够推断出这些类型.

小智 8

确定基于参数调用的函数的过程称为重载解析,以及使用它的情况下的标准列表:

13.3过载分辨率[over.match]

2重载分辨率选择要在语言中的七个不同上下文中调用的函数:

(2.1) - 调用函数调用语法(13.3.1.1.1)中指定的函数;

(2.2) - 调用一个函数调用操作符,一个指向函数的指针转换函数,一个指向函数的引用转换函数,或一个在该对象中命名的类对象的函数转换函数.函数调用语法(13.3.1.1.2);

(2.3) - 调用表达式中引用的运算符(13.3.1.2);

(2.4) - 调用类对象的直接初始化(8.5)的构造函数(13.3.1.3);

(2.5) - 为类对象的复制初始化(8.5)调用用户定义的转换(13.3.1.4);

(2.6) - 从类类型的表达式(13.3.1.5)调用转换函数以初始化非类类型的对象; 和

(2.7) - 调用转换函数以转换为glvalue或类prvalue,引用(8.5.3)将直接绑定到该值(13.3.1.6).

其中,唯一适用于常规函数的是2.1,这需要一个f(args)只告诉调用者结果的上下文.

所以,你要求的是无法做到的.不管怎样,不完全是这样.

现在,这取决于你想要完成的任务,也有一些事情可能的:

如果您知道确切的签名template <typename T> int hello(A<T> a, A<T> b),则可以获得指向该函数的指针:给定,您可以使用以下方式获取地址:static_cast<int(*)(A<int>,A<int>)>(hello).但是,要使其工作,您需要知道返回类型(您可以使用它获得decltype),并且您需要知道参数类型(可能与参数类型不同,并且您不能使用获得可靠的).

也可以获得一个指向函数的指针,该函数在被调用时将具有与以下相同的效果hello:

auto callable = +[](A<int> a, A<int> b) { return hello(a, b); };
Run Code Online (Sandbox Code Playgroud)

[](A<int> a, A<int> b) { return hello(a, b); }没有任何捕获创建一个lambda,且无任何捕获的lambda可以隐含转换为匹配类型的函数指针.该+部队使用该转换,而不需要类型来阐明.

但是,这将不具有相同的地址hello,因此可能不适合后续比较.

这是你能得到的最好的.