Рассмотрим этот код:
template<typename T>
class Base
{
template<typename U>
friend void f(void *ptr) {
static_cast<Base<U>*>(ptr)->run();
}
protected:
virtual void run() = 0;
};
class A : public Base<A>
{
protected:
virtual void run() {}
};
/*
class B : public Base<B>
{
protected:
virtual void run() {}
};
*/
Теперь он прекрасно компилируется ( ideone ).Но если я раскомментирую определение B
, то оно выдаст следующую ошибку ( ideone ):
prog.cpp: In instantiation of ‘Base<B>’:
prog.cpp:20: instantiated from here
prog.cpp:6: error: redefinition of ‘template<class U> void f(void*)’
prog.cpp:6: error: ‘template<class U> void f(void*)’ previously defined here
Я знаю ( хорошо, я думаю, что знаю ) причина, по которой он выдает эту ошибку.
Итак, мой вопрос:
Как избежать ошибки переопределения в случае определения в классе шаблона функции-друга?
Пока я предоставляю определение основного шаблона (не специализация) внутри класса, я получу эту ошибку.Существует также еще одна проблема с определением основного шаблона таким образом: он создает все экземпляры f
шаблона функции friend
из всех экземпляров Base
шаблона класса, которых я также хотел бы избежать.Я хочу сделать f<T>
другом Base<T>
, но не f<U>
другом Base<T>
, если U
и T
не совпадают.В то же время я также хочу дать определение внутри класса.Возможно ли это?