假设我有以下代码:
recvfrom()
两个compute()调用将仅实例化一个函数模板,即compute <1,2,3>还是取决于参数而存在两种不同的实例化?
我想通过使用指向特定实例的函数指针来确认这一点,看看是否可以使用相同的函数指针使用2个不同的参数集调用函数,但是在调用fp的行中出现以下错误(a,b):
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); }
答案 0 :(得分:6)
参数包是贪婪的。
&compute<1,2,3>
用伪代码&compute< U1={1,2,3}, U2={} >
。
获取指向各个计算的指针很烦人。
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; }
};
然后我们可以做
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>>{}();
和fp1
和fp2
是不同的类型。
答案 1 :(得分:3)
两个
compute()
调用会只实例化一个函数模板,即compute<1,2,3>
还是根据参数有两个不同的实例化?
非常不同。编写compute(a, b)
时调用的函数是采用Matrix<1>
和Matrix<2,3>
的函数。编写compute(c, d)
时调用的函数是采用Matrix<1,2>
和Matrix<3>
的函数。
但是当您写这篇文章时:
auto fp = &compute<1,2,3>;
无法说出这些值指的是U1...
或U2...
中的哪个。每个编译器所做的就是将所有参数都包含在第一个包中-因此fp
最终成为int(*)(Matrix<1,2,3>, Matrix<>)
。换句话说,此版本是采用Matrix<1,2,3>
和Matrix<>
的函数。这与两个原始呼叫都不相同。
事实上,由于两个原始调用是对两个不同函数的调用,因此不可能使用指向两个函数的单个函数指针。相反,您可以做的是构造一个执行正确操作的函数 object :
auto fp = [](auto m1, auto m2){ return compute(m1, m2); };
这可以(尝试),但是却是另一回事。
答案 2 :(得分:0)
不同的方法。不需要整数序列或临时函子对象。链接:https://gcc.godbolt.org/z/W4V6gf
template<int... V1>
struct Mat1 {
template<int... V2>
struct Mat2 {
using compute_type = int(*)(Matrix<V1...>, Matrix<V2...>);
};
};
void foo() {
{
using compute_type = Mat1<1>::Mat2<2,3>::compute_type;
compute_type ct = compute;
ct(a, b);
//ct(c, d); //This wont compile
}
{
using compute_type = Mat1<1,2>::Mat2<3>::compute_type;
compute_type ct = compute;
ct(c, d);
//ct(a, b); //This wont compile
}
}
更通用
template<int... Us>
struct Matrix{};
Matrix<1> a; Matrix<2,3> b;
Matrix<1,2> c; Matrix<3> d;
template<int... U1, int... U2>
auto compute(Matrix<U1...>, Matrix<U2...>){return 0;}
template<class Scalar, template<Scalar...> class MatType>
struct VArg {
template<Scalar... V1>
struct arg1 {
using type = MatType<V1...>;
template<Scalar... V2>
struct arg2 {
using type1 = type;
using type2 = MatType<V2...>;
};
};
};
template<class args_gen>
struct compute_type {
using type = int(*)(typename args_gen::type1, typename args_gen::type2);
};
void foo() {
using int_matrix_gen = VArg<int, Matrix>;
{
using args_ab = int_matrix_gen::arg1<1>::arg2<2,3>;
compute_type<args_ab>::type cptr = compute;
cptr(a, b);
//cptr(c, d); This wont compile
}
{
using args_cd = int_matrix_gen::arg1<1,2>::arg2<3>;
compute_type<args_cd>::type cptr = compute;
cptr(c, d);
//cptr(a, b); This wont compile
}
}
更多泛型:https://gcc.godbolt.org/z/EF6OK9支持具有3个Matrix参数的函数。