Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 重载函数候选匹配问题_C++_Templates_Overloading_Typeid - Fatal编程技术网

C++ 重载函数候选匹配问题

C++ 重载函数候选匹配问题,c++,templates,overloading,typeid,C++,Templates,Overloading,Typeid,我不确定我是否理解这里发生的事情的细微差别,并希望得到一个解释 我正在从模板包装器调用几个重载函数,lapack\u gesvd\u nothrow。从这里,我将单独的FXN称为: 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, f

我不确定我是否理解这里发生的事情的细微差别,并希望得到一个解释

我正在从模板包装器调用几个重载函数,
lapack\u gesvd\u nothrow
。从这里,我将单独的FXN称为:

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);
  }
以下是候选匹配项:

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>*}’
候选人包括:
注:无效nm::数学::lapack\u gesvd(字符*、字符*、整数*、整数*、浮点*、整数*、浮点*、浮点*、整数*、浮点*、整数*、整数*)
注:应试者需要14个参数,提供15个
void nm::math::lapack_gesvd(char*,char*,int*,int*,double*,int*,double*,double*,int*,double*,int*,double*,int*)
注:应试者需要14个参数,提供15个
无效nm::math::lapack_gesvd(char*,char*,int*,int*,nm::Complex64*,int*,nm::Complex64*,nm::Complex64*,int*,nm::Complex64*,int*,nm::Complex64*,int*,int*,浮点*)
注意:参数5没有从“float*”到“nm::Complex64*{aka nm::Complex*}”的已知转换
我很困惑,为什么现在会出现取消引用,因为它似乎是必需的
错误:没有它,从“int”到“int*”的转换无效,并且在最近的重载之前是必需的

非常感谢您的解释和解决方案!谢谢

编辑

这可能归结为:

如果我调用
lapack\u gesvd\u nothrow(…)
然后执行typeid比较
If(typeid(DType)==typeid(CType))
。。。我会得到预期的答案吗?现在看来,情况并非如此。如何正确检查此比较的模板类型?

TL;DR

您正在这样做:

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
}
模板
void foo(…){
//假设U和V是不同的
}
模板
void foo(…){
//假设两种类型相同
}
为什么会这样

编译器将替换编译期间指定的类型。这样,如果使用初始化,它将使用float更改if

lapack_gesvd_nothrow<float, float>(...)

if (typeid(float) == typeid(float))
lapack\u gesvd\u nothrow(…)
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);
}
if(typeid(float)=typeid(float)){
lapack_gesvd(作业、作业、维护和维护、A和lda、S、U和ldu、VT和ldvt、工作、工作和信息);
}否则{
CType*RWORK=重新解释铸造(RWORK);
lapack_gesvd(作业、作业、维护、维护、保养、保养、保养、保养、保养、保养、保养、保养、保养、保养、保养、保养、保养、保养、保养、保养、保养、保养和信息);
}
编译器将看到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);
voidfoo(float,float){};
voidfoo(int,int,int){};
模板(){
...
U a、b、c;
如果(…)
foo(a,b),;
其他的
foo(a、b、c);
...
}
//将更改为
浮子a、b、c;
如果(…)
foo(a,b),;
其他的
foo(a、b、c);

由于没有foo(float,float,float),导致else部分出现编译器错误。

函数正在等待nm::Complex64*但您正在传递float*请查看第一个函数定义。就是那个。。。1) 获取14个参数2)获取所有
float*
而不是任何
nm::Complex64*
我假设您要调用第二个函数,因为您要传递15个参数。(注:候选人需要14个论点,提供15个论点)观点正确。。。我想你可能有这个。我现在怀疑这是我对
DType
CType
的比较。如果我调用15个参数的版本,所有浮动,那就错了。很好。这表明我的比较应该有效
typeid(double)==typeid(double)
不应为false。此外,模板生成之前编译和运行的内部代码。问题是编译器将更改浮点的CType。之后将尝试编译代码。为了让您看到
typeid(double)=typeid(double)
不是问题,您可以尝试将
if
更改为
if(true)
,然后看看会发生什么。
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);