2013-08-02 3 views
2

Я не уверен, что понимаю нюансы происходящего здесь и надеялся на объяснение.Проблемы с совместимостью с перегруженной функцией

Я вызываю несколько перегруженных функций из шаблонной обертки, 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); 
} 

Он работал, пока не объявлен второй типа перегрузки (я перегружен с поплавком и двойным, никаких проблем), но теперь он не бросает несколько ошибок и, кажется, не подсчитывают мои аргументы хорошо.

Я называю это от функции, принял аргументы, как:

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*' без него и требуется до последней перегрузки.

Ваши объяснения и решения были бы очень признательны! Благодаря!

EDIT

Он может спуститься:

Если я позвоню lapack_gesvd_nothrow<float, float>(...), а затем выполнить сравнение TypeID if (typeid(DType) == typeid(CType)) ... Смогу ли я получить ожидаемый ответ? Сейчас это не так. Как я могу правильно проверить типы шаблонов для этого сравнения?

+0

Функция ждет nm :: Complex64 *, но вы проходите float * – wendelbsilva

+0

Посмотрите на первое определение функции. Это то, что ... 1) принимает 14 аргументов 2) принимает все 'float *' вместо любого 'nm :: Complex64 *' – Ryanmt

+0

Я предположил, что вы хотите вызвать вторую функцию, потому что вы передаете 15 аргументов , (примечание: кандидат ожидает 14 аргументов, 15 предоставлено) – wendelbsilva

ответ

1

TL; DR

Вы делаете это:

if (false) { 
    // some language rule violation here 
} else { 
    // correct code here 
} 

Обе стороны, если-иначе необходимости быть скомпилированы.

Решение

Вы можете частично специализировать шаблон.

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 
} 

Почему это происходит

компилятор заменителя типа, указанного во время компиляции.Таким образом, если вы инициализировать, она будет меняться, если с поплавком

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); 
} 

компилятор увидит, что тип А является поплавок. Первая часть инструкции 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); 

Результат в ошибке компилятора в остальном части, потому что нет никакого Foo (поплавок, поплавок, поплавок).

+0

'typeid (double) == typeid (double)' не должно быть ложным. Кроме того, код внутри, который был компиляции и запущен до шаблонов. – Ryanmt

+0

Проблема заключается в том, что компилятор изменит CType для float. Затем попытается скомпилировать код. – wendelbsilva

+1

Чтобы увидеть, что 'typeid (double) == typeid (double)' не является проблемой, вы можете попробовать изменить 'if' на' if (true) 'и посмотреть, что произойдет. – wendelbsilva

Смежные вопросы