Suppose say I have this code:
template<int... Us>
struct Matrix{};
template<int... U1, int... U2>
auto compute(Matrix<U1...>, Matrix<U2...>){return 0;}
Matrix<1> a; Matrix<2,3> b;
Matrix<1,2> c; Matrix<3> d;
int main(){
compute(a,b);
compute(c,d);
auto fp = &compute<1,2,3>;
fp(a,b);
fp(c,d);
}
Would the two compute() calls instantiate just one function template i.e. compute<1,2,3> or would there be two different instantiations depending on the arguments?
I wanted to confirm this by taking a function pointer to the particular instantiation and see if I could call the function with the 2 different sets of arguments using the same function pointer but I get the following errors at the line where I call fp(a,b):
[x86-64 gcc 8.2 #1] error: could not convert 'a' from 'Matrix<#'nontype_argument_pack' not supported by dump_expr#<expression error>>' to 'Matrix<#'nontype_argument_pack' not supported by dump_expr#<expression error>>'
Parameter packs are greedy.
&compute<1,2,3>
is, in pseudo-code, &compute< U1={1,2,3}, U2={} >
.
Getting a pointer to the individual computes is annoying.
template<class U1s, class U2s>
struct get_computer;
template<int...U1, int...U2>
struct get_computer<std::integer_sequence<int, U1...>, std::integer_sequence<int, U2...>> {
using compute_type = int(*)(Matrix<U1...>, Matrix<U2...>);
compute_type operator()() const { return compute; }
};
we can then do
auto fp1 = get_computer<std::integer_sequence<int, 1>, std::integer_sequence<int, 2, 3>>{}();
auto fp2 = get_computer<std::integer_sequence<int, 1, 2>, std::integer_sequence<int, 3>>{}();
and fp1
and fp2
are different types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With