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

10 c++ templates pointers function

对不起,非常重要的代码(也在这里wandbox上)

#include <memory>
#include <cstdio>

template< typename T, size_t N, typename ... Args >
 void test_1 ( Args ... args)
 {
    using namespace std;

    if constexpr( 1 > (sizeof... (args))  ) {
         return;
    }
    else 
    {
    auto    arg_list [[maybe_unused]] = { args ... };
    }
 }
    template< typename T, size_t N, typename ... Args >
    void test_2 ( Args ... args)
    {
      auto  arg_list [[maybe_unused]] = { args ... };
    }
  ///////////////////////////////////////////////////////////
 int main()
 {
     test_1<int,3>(1,2,3);
     test_2<int,3>(1,2,3);

// taking the function pointer (aka address of) leads to
// full instantiation of function template 
constexpr auto adr_1 [[maybe_unused]] = std::addressof(test_1<int,3>);
// no can do --> constexpr auto adr_2 = std::addressof(test_2<int,3>);

}
Run Code Online (Sandbox Code Playgroud)

所以.从上面可以看出,模板函数指针(也就是地址)会导致函数模板的完全实例化.

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

     // 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>);
Run Code Online (Sandbox Code Playgroud)

现在.怎么能绕过这个呢?请注意上面的代码意味着编译器执行此操作:

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

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

这就是为什么人们可以采用上述地址test1而不是test_2.也许对我而言,这根本没有任何意义.通过这个,我特别指的是编译函数模板实例,就好像通过使用void参数调用它一样?反过来意味着,没有constexpr-if人会很难写上面的test_1.反过来(几乎)意味着没有c ++ 11而没有c ++ 14.

请讨论......

Edg*_*jān 6

这是一种不幸的事.如果一个人获取模板函数实例化的地址,那将产生一个完整的实例化.

这不是不幸的.这就是语言的工作方式.如果获得模板函数的地址(从函数模板实例化的函数),则此函数必须存在.换句话说,它必须从相应的功能模板中实例化.

怎么能绕过这个呢?

没有办法.这是一种完美的预期行为.

  • 函数模板就是这样:一个模板。在实例化之前,它不存在于实际程序中。你不能取一个不存在的东西的地址。如果你不想实例化某个特定版本的模板函数,你可以传递这些类型参数:`test_2&lt;int, 3, char, double, int&gt;` 等。 (2认同)