Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;如何获取模板函数实例的地址?_C++_Function_Templates_Pointers - Fatal编程技术网

C++ c++;如何获取模板函数实例的地址?

C++ c++;如何获取模板函数实例的地址?,c++,function,templates,pointers,C++,Function,Templates,Pointers,很抱歉,这是一段非常重要的代码(也在上) #包括 #包括 模板 无效测试_1(Args…Args) { 使用名称空间std; 如果constexpr(1>(sizeof…(args))){ 返回; } 其他的 { 自动参数列表[[可能未使用]]={args…}; } } 模板 无效测试_2(Args…Args) { 自动参数列表[[可能未使用]]={args…}; } /////////////////////////////////////////////////////////// int

很抱歉,这是一段非常重要的代码(也在上)

#包括
#包括
模板
无效测试_1(Args…Args)
{
使用名称空间std;
如果constexpr(1>(sizeof…(args))){
返回;
}
其他的
{
自动参数列表[[可能未使用]]={args…};
}
}
模板
无效测试_2(Args…Args)
{
自动参数列表[[可能未使用]]={args…};
}
///////////////////////////////////////////////////////////
int main()
{
测试_1(1,2,3);
试验2(1,2,3);
//使用函数指针(也称为的地址)将导致
//函数模板的完全实例化
constexpr auto adr_1[[可能未使用]]=std::addressof(测试1);
//无法执行-->constexpr auto adr_2=std::addressof(test_2);
}
所以。从上面可以看出,使用模板函数指针(又称地址)将导致函数模板的完整实例化

这是一种不幸。如果获取模板函数实例化的地址,将生成完整的实例化。即使那个永远不会被召唤的人

     // pointer to instance made but instance never used
     constexpr auto adr_5 [[maybe_unused]] = std::addressof(test_1<float,9>);
     // pointer to instance made but instance never used
     constexpr auto adr_of_big_foot_gun 
           [[maybe_unused]] = std::addressof(test_1<bool,99>);
     // pointer to instance made but instance never used
     constexpr auto adr_of_crazy [[maybe_unused]] = 
                 std::addressof(test_1<char, 0xFFFF>);
//指向已创建但从未使用的实例的指针
constexpr auto adr_5[[可能未使用]]=std::addressof(测试1);
//指向已创建但从未使用的实例的指针
constexpr自动adr__大脚___________________________
[[maybe_unused]]=std::addressof(test_1);
//指向已创建但从未使用的实例的指针
constexpr自动adr_疯狂[[可能未使用]]=
std::addressof(测试1);
现在。如何才能避免这种情况?请注意,上述代码表示编译器执行以下操作:

        // this line
        std::addressof( test_2<int,3> )

        // provokes something like this
        // which needs to be compiled
        test_2<int,3>(void) ;
//这一行
标准::地址(测试2)
//引起类似的事情
//需要进行编译
试验2(无效);
这就是为什么可以使用上面的
test1
地址,但不能使用
test\u 2
。也许对我来说,这毫无意义。我的意思是编译函数模板实例,就像用void参数调用它一样?这反过来意味着,如果没有
constexpr if
1,您将很难编写上述测试。这反过来(几乎)意味着没有c++11和c++14

请讨论

这是一种不幸。如果一个模板的地址 函数实例化,它将生成完整的实例化

这并不不幸。这就是语言的工作原理。如果获得模板函数(从函数模板实例化的函数)的地址,则该函数必须存在。换句话说,它必须从相应的函数模板中实例化

如何才能避免这种情况


没有办法。这是一个非常合理的预期行为。

为了获取地址,您需要一个完整的实例化,否则就没有什么可指向的。请记住,编译器不会在运行时完成部分参数化模板的生成。即使在只知道函数指针的不同调用站点上,编译器也无法实例化模板,因为它可能不知道它

test2
(或就此而言
test1
的实例)是不同的函数,根据参数的不同,它们不可能有一个地址。例如,
test2
不同于
test2
,它接受不同的参数并使用它们做不同的事情。它们的地址不同,相应函数指针的类型也不同

根据您使用地址的方式,您可能能够在编译时通过模板参数化(如果指针本身是已实例化或未实例化模板的一部分)或constepr if构造将其关闭


同样,如果在所有对象文件中都没有对指针的引用,链接器可能会使用正确的选项删除不必要的实例化模板,但这并不能保证,您仍将支付编译时成本。

没有办法避免这种情况。有些东西需要存在才能有地址。您希望未实例化的函数模板专门化的具体地址是什么?因此,您希望避免实例化,但您希望的指针值是什么?您是否只需要函数类型?您是否正在尝试进行类似“函数指针被调用时函数被实例化”这样的优化?如果是这样,这是不可能的,因为C++只在编译时执行这个技巧。如果您对
adr_1==nullptr
没有问题,那么只需
typedef
您的函数指针类型并将其分配给
nullptr
。是的,这正是一件非常好的事情。注意
std::addressof(test_1)!=std::addressof(test_1)
,因此无效的
test_2
的地址无论如何都是无用的。谢谢您的回答。也许对我来说,这毫无意义。我的意思是编译fun模板实例,就像用void参数调用它一样。这反过来意味着,如果没有
constexpr if
1,您将很难编写上述测试。这反过来(几乎)意味着没有c++11和c++14。@Edgar Rokjan“你不能专门化函数模板”。我想你能吗@我失去了一个重要的词:部分。非常感谢您的评论@phön,我从问题中删除了“专门化”一词,因为它与Edgar正确的用例无关。在实例化之前,它不存在于实际程序中。你不能获取不存在的东西的地址。如果不想实例化某个特定版本的模板函数,可以传递这些类型
        // this line
        std::addressof( test_2<int,3> )

        // provokes something like this
        // which needs to be compiled
        test_2<int,3>(void) ;