Я получаю действительно странное сообщение об ошибке из gcc 4.6 о функции-члене шаблона. Вот минимальный пример:
template<typename T>
class Pimpl
{
public:
Pimpl(const Pimpl&) {}
private:
T* clone_(const T*);
};
template<typename T>
template<typename P>
T*
Pimpl<T>::clone_(const T*)
{
return new P(static_cast<const P&>(*p));
}
Вот ошибка:
$ c++ -c y.cpp
y.cpp:14:1: error: prototype for ‘T* Pimpl<T>::clone_(const T*)’ does not match any in class ‘Pimpl<T>’
y.cpp:8:8: error: candidate is: T* Pimpl<T>::clone_(const T*)
Обратите внимание, что несовпадающий прототип в точности совпадает с прототипом-кандидатом.
Что дает?
Они разные из-за template <typename P>
, Сообщение об ошибке Comeau (генерируется в http://www.comeaucomputing.com/tryitout) выдвигает на первый план проблему, с которой вы столкнулись:
error: template nesting depth does not match the previous declaration of function "Pimpl<T>::clone_"
В целом стоит отметить, что:
(a) Компилятор Comeau известен как выдающий особенно хорошие сообщения об ошибках.
(б) Компиляция с несколькими компиляторами часто дает вам понимание того, чего вы могли бы не иметь иначе.
Если вы хотите шаблон участника, вы должны объявить его так:
template <typename T>
class Pimpl
{
// ...
template <typename P>
static P * clone(T const * p)
{
return new P(static_cast<P const &>(*p));
}
};
Я также сделал шаблон участника static
потому что он, кажется, не зависит от экземпляра объекта, и я определил его встроенным, потому что вы все равно должны предоставить определение шаблона в заголовке, и я исправил тип возвращаемого значения. (Но я не вижу, как clone
функция имеет какой-то смысл …)