抱歉,这段代码有些复杂(在此处也是如此)
。#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>);
}
因此,从上面的内容可以看出,获取模板函数指针(即地址)会导致函数模板的完全实例化。
这有点不幸。如果获取模板函数实例化的地址,那么将产生一个完全实例化。即使永远不会调用该函数。
// 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>);
现在,如何绕过这个问题呢?请注意上述代码意味着编译器会执行以下操作:
// this line
std::addressof( test_2<int,3> )
// provokes something like this
// which needs to be compiled
test_2<int,3>(void) ;
这就是为什么我们可以获取上面的
test1
地址,但不能获取test_2
的原因。对我来说,这根本没有任何意义。而且,具体来说,这意味着编译函数模板实例,好像使用空参数调用它一样?换句话说,如果没有constexpr-if
,那么很难编写上面的test_1。这又(几乎)意味着没有c++11和c++14。请讨论...
adr_1 == nullptr
,那么只需将你的函数指针类型进行typedef
并将其赋值为nullptr
即可。 - ivaigultstd::addressof(test_1<int,3>) != std::addressof(test_1<int,3,char>)
,因此无效的test_2<int,3>
地址无论如何都是无用的。 - Jarod42