10 c++ templates pointers function
#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.
请讨论......
这是一种不幸的事.如果一个人获取模板函数实例化的地址,那将产生一个完整的实例化.
这不是不幸的.这就是语言的工作方式.如果获得模板函数的地址(从函数模板实例化的函数),则此函数必须存在.换句话说,它必须从相应的功能模板中实例化.
怎么能绕过这个呢?
没有办法.这是一种完美的预期行为.