Sorry for the non-trivial code (also on the wandbox here )
#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>);
}
So. From the above, it appears taking the template function pointer (aka address of) leads to the full instantiation of a function template.
Which is kind-of-a unfortunate. If one takes the address of template function instantiation, that will produce a full instantiation. Even if the one is never to be called.
// 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>);
Now. How can this be circumvented? Please note the above code means that compiler does this :
// this line
std::addressof( test_2<int,3> )
// provokes something like this
// which needs to be compiled
test_2<int,3>(void) ;
This is why one can take the address of test1
above but not test_2
. Perhaps to me, this does not make any sense at all. And by this, I specifically mean compiling the function template instance as if by calling it with the void arguments? Which in turn means, without constexpr-if
one would be hard-pressed to write test_1 above. Which in turn (almost) means no c++11 and no c++14.
Please discuss ...