Ошибка компиляции в явно созданных шаблонных методах

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

main.cpp

#include <stdio.h>
#include <stdlib.h>
#include <foo.h>
#include <bar.h>

int main(int argc, char **argv){
    ...
    int nParam;
    ...

    CFoo<float> * pFoo = NULL;
    pFoo = new CFoo<float>();

    CBar<float> * pBar = NULL;
    pBar = pFoo->doSomething(nParam); // error: no matching function for call to ‘CFoo<float>::doSomething(int)’

    ...

    delete pFoo;
    delete pBar;

    return (0);
}

foo.h

#include <bar.h>

template < class FOO_TYPE >
class CFoo{

    public:

        ...

        template < class BAR_TYPE >
        CBar<BAR_TYPE> * doSomething(int);
        ...
};

foo.cpp

template < class FOO_TYPE >
template < class BAR_TYPE >
CBar<BAR_TYPE> * CFoo<FOO_TYPE>::doSomething(int nParam){
    ...
}
#include "foo-impl.inc" 

foo-impl.inc

template class CFoo<float>;
template class CFoo<double>;

template CBar<float>* CFoo<float>::doSomething( int );
template CBar<double>* CFoo<float>::doSomething( int );
template CBar<double>* CFoo<double>::doSomething( int );
template CBar<float>* CFoo<double>::doSomething( int );

/*
I also tried the explicit instantiation in the last line, but I get the error below:
template-id ‘doSomething<CBar<float>*>’ for ‘CBar<float>* CFoo<float>::doSomething(int)’ does not match any template declaration
*/
// template CBar<float>* CFoo<float>::doSomething < CBar<float> * > ( int ); 

Учтите, что мне нужно вызвать метод doSomething внутри member function третьего класса.

myclass.cpp

template < class FOO_TYPE, class BAR_TYPE >
void CMyClass<FOO_TYPE, class BAR_TYPE>::doSomeWork(CFoo<FOO_TYPE> * pFoo){
    ...
    int nParam;
    ...
    CBar<BAR_TYPE> * pBar = NULL;
    pBar = pFoo->doSomething<BAR_TYPE>(nParam); //error: expected primary-expression before ‘>’ token

    delete pBar;
    ...
} 

Обратите внимание, что у меня была аналогичная проблема, которую я недавно опубликовал в этом forum, но, пытаясь адаптировать предложение к моему коду, я не смог исправить ошибку. Надеюсь, мой пост верен.


person Javier    schedule 09.03.2011    source источник


Ответы (1)


Компилятор не может вывести аргументы шаблона - он не знает, хотите ли вы вызвать CFoo<float>::doSomething<float>(int), CFoo<float>::doSomething<unsigned int>(int) или что-то еще. Итак, вы должны явно указать, какие аргументы шаблона:

// Explicitly call the function with BAR_TYPE=float
pBar = pFoo->doSomething<float>(1);
person Adam Rosenfield    schedule 09.03.2011
comment
спасибо, что исправил ошибку! Я думал, что, поскольку pFoo относится к типу float, компилятору должно быть достаточно знать, какую функцию вызывать. С другой стороны, когда действительно явное создание как: template CBar<float>* CFoo<float>::doSomething < CBar<float> * > ( int );? - person Javier; 09.03.2011
comment
@Javier: Нет - компилятор может вывести аргументы шаблона из переданных параметров (например, если у вас было template <class C> void doSomething(C), тогда, если вы передали целочисленный параметр, он бы вывести этот C = int), но не из того, что происходит с возвращаемым значением. Вы всегда можете выполнить явное создание экземпляра, но это не всегда может быть хорошей идеей; Я не уверен, что этот фрагмент, который вы опубликовали, должен означать, поскольку он синтаксически неверен. - person Adam Rosenfield; 09.03.2011
comment
Спасибо за разъяснения! Что касается моего фрагмента, если вы имеете в виду 1, поскольку мне не удалось найти ошибку, я пытался отладить ее вручную. Фактически, это переменная, переданная в качестве аргумента. Кроме того, знаете ли вы, когда действителен следующий экземпляр: template CBar<float>* CFoo<float>::doSomething < CBar<float> * > ( int );? - person Javier; 09.03.2011
comment
@ Хавьер: синтаксис template CBar<float*> недействителен. Если вы пытаетесь определить специализацию шаблона doSomething с помощью BAR_TYPE=float, напишите template<> CBar<float>* CFoo<float>::doSomething>( int ) { ... }. Обратите внимание на дополнительный <> после template. - person Adam Rosenfield; 09.03.2011
comment
большой! Теперь я пытаюсь вызвать doSomething внутри функции-члена третьего класса: pBar = pFoo->doSomething<BAR_TYPE>(nParam);. При этом я получаю ошибку компиляции. Я вставил новый абзац в свой исходный пост, где показываю ошибку. Почему этот звонок недействителен? Я в основном заменил <float> вызова функции в main.cpp на <BAR_TYPE>. - person Javier; 10.03.2011