我不确定我是否理解这里发生的事情的细微差别,希望得到解释。
我正在从一个模板化包装器中调用几个重载函数,lapack_gesvd_nothrow
.从那里,我调用像这样的个人 fxns:
inline void lapack_gesvd(char *jobu, char *jobvt,
int *m, int *n,
float *a, int *lda,
float *s,
float *u, int *ldu,
float *vt, int *ldvt,
float *work, int *lwork,
int *info) {
sgesvd_(jobu, jobvt, m, n,
a, lda, s, u, ldu,
vt, ldvt, work, lwork,
info);
}
inline void lapack_gesvd(char *jobu, char *jobvt,
int *m, int *n,
nm::Complex64 *a, int *lda,
nm::Complex64 *s,
nm::Complex64 *u, int *ldu,
nm::Complex64 *vt, int *ldvt,
nm::Complex64 *work, int *lwork, float *rwork,
int *info) {
cgesvd_(jobu, jobvt, m, n,
a, lda, s, u, ldu,
vt, ldvt, work, lwork,
rwork, info);
}
它一直有效,直到我声明了第二种类型的重载(我已经用 float 和 double 重载了,没问题),但现在它抛出了一些错误并且似乎没有很好地计算我的参数。
我从一个接受参数的函数中调用它:
template <typename DType, typename CType>
static int lapack_gesvd_nothrow(char *jobu, char *jobvt,
int m, int n,
void *a, int lda,
void *s,
void *u, int ldu,
void *vt, int ldvt,
void *work, int lwork,
int info, void *rwork) {
....
DType* UPCASE = reinterpret_cast<DType*>(lowercase);
....
if (typeid(DType) == typeid(CType)) {
lapack_gesvd(jobu, jobvt, &m, &n, A, &lda, S, U, &ldu, VT, &ldvt, WORK, &lwork, &info);
} else {
CType* RWORK = reinterpret_cast<CType*>(rwork);
lapack_gesvd(jobu, jobvt, &m, &n, A, &lda, S, U, &ldu, VT, &ldvt, WORK, &lwork, RWORK, &info);
}
我实际上只做 reinterpret_casts
两者之间。
这是它显然正在寻找的 fxn:
error: no matching function for call to ‘lapack_gesvd(char*&, char*&, int*, int*, float*&, int*, float*&, float*&, int*, float*&, int*, float*&, int*, float*&, int*)
这里是候选匹配项:
candidates are:
note: void nm::math::lapack_gesvd(char*, char*, int*, int*, float*, int*, float*, float*, int*, float*, int*, float*, int*, int*)
note: candidate expects 14 arguments, 15 provided
void nm::math::lapack_gesvd(char*, char*, int*, int*, double*, int*, double*, double*, int*, double*, int*, double*, int*, int*)
note: candidate expects 14 arguments, 15 provided
void nm::math::lapack_gesvd(char*, char*, int*, int*, nm::Complex64*, int*, nm::Complex64*, nm::Complex64*, int*, nm::Complex64*, int*, nm::Complex64*, int*, float*, int*)
note: no known conversion for argument 5 from ‘float*’ to ‘nm::Complex64* {aka nm::Complex<float>*}’
我很困惑为什么取消引用现在出现,而它似乎是必需的 error: invalid conversion from 'int' to 'int*'
没有它,并且在最近的重载之前需要。
非常感谢您的解释和解决方案!谢谢!
编辑
它可能归结为:
如果我调用 lapack_gesvd_nothrow<float, float>(...)
然后进行typeid比较if (typeid(DType) == typeid(CType))
...我会得到预期的答案吗?现在看来,情况并非如此。如何正确检查此比较的模板类型?
最佳答案
长话短说
你正在这样做:
if (false) {
// some language rule violation here
} else {
// correct code here
}
if-else 的两边都需要是可编译的。
解决方案
您可以部分特化模板。
template <class U, class V>
void foo(...){
//assume U and V are different
}
template <class U>
void foo<U, U>(...){
//assume both types are the same
}
为什么会这样
编译器替换编译期间指定的类型。这样,如果你用 初始化,它会用 float 改变 if
lapack_gesvd_nothrow<float, float>(...)
if (typeid(float) == typeid(float))
这样,代码就变成了这样:
if (typeid(float) == typeid(float)){
lapack_gesvd(jobu, jobvt, &m, &n, A, &lda, S, U, &ldu, VT, &ldvt, WORK, &lwork, &info);
} else {
CType* RWORK = reinterpret_cast<CType*>(rwork);
lapack_gesvd(jobu, jobvt, &m, &n, A, &lda, S, U, &ldu, VT, &ldvt, WORK, &lwork, RWORK, &info);
}
编译器会发现 A 的类型是 float。 if-else 语句的第一部分是正确的。虽然,在第二部分不是。这是编译器将如何看待它的示例:
void foo(float, float){};
void foo(int, int, int){};
template <class U>(){
...
U a, b, c;
if (...)
foo(a, b);
else
foo(a, b, c);
...
}
//Will be changed to
float a, b, c;
if (...)
foo(a, b);
else
foo(a, b, c);
导致 else 部分出现编译错误,因为没有 foo(float, float, float)。
关于c++ - 重载函数候选匹配问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18025656/