Шаблон класса с функцией шаблона - PullRequest
6 голосов
/ 10 августа 2011

Может кто-нибудь сказать, что не так с этим фрагментом кода?

template<class X>
class C {
public:
    template<class Y> void f(Y); // line 4
};

template<class X, class Y>
void C<X>::f(Y y) { // line 8
    // Something.
}

int main() {
    C<int> c;
    char a = 'a';
    c.f(a);
    return 0;
}

Компиляция:

$ g++ source.cpp 
source.cpp:8: error: prototype for ‘void C<X>::f(Y)’ does not match any in class ‘C<X>’
source.cpp:4: error: candidate is: template<class X> template<class Y> void C::f(Y)

Теперь я могу выполнить задачу, объявив и определив функцию в строке 4, но каковы будут последствия объявления и определения функции одновременно по сравнению с выполнением ее отдельно? (Это не обсуждение объявления функции в заголовке или в исходном файле)

Примечание: Я видел этот вопрос , но кажется, что единственная часть, которая меня интересует, была оставлена ​​отдельно = (

Ответы [ 3 ]

14 голосов
/ 10 августа 2011

Компилятор уже говорит вам ответ. Класс C является шаблоном с одним параметром, а функция-член f является функцией-шаблоном, и вы должны определить ее так же:

template <class X>
template <class Y>
void C<X>::f(Y y)
{
    // Something.
}

Если вы определите функцию на сайте объявления, вы неявно объявите ее inline; это практически единственная разница. Конечно, могут быть стилистические соображения, например, никогда не помещать определения функций в определения классов.

Как вы правильно заметили, вам все равно придется предоставить определение в заголовочном файле, поскольку вам нужно будет создавать экземпляр шаблона всякий раз, когда вы его используете, и, таким образом, вам нужен доступ ко всем определениям.

1 голос
/ 10 августа 2011

Ошибка говорит вам точно, ваш код должен выглядеть так:

template<class X>
class C {
public:
    template<class Y> void f(Y); // line 4
};

template<class X> template<class Y>
void C<X>::f(Y y) { // line 8
    // Something.
}

int main() {
    C<int> c;
    char a = 'a';
    c.f(a);
    return 0;
}

Ваш класс не определен как template<class X, class Y>

0 голосов
/ 10 августа 2011

Кроме того, предпочтительно использовать ключевое слово typename вместо class в списке аргументов шаблона.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...