Вы не можете объявить переменные-члены шаблона.Но даже если вы могли бы объявить _recv_callback
с типом шаблона F1
, F1
должен быть определен во время компиляции.Так что же будет с оператором присваивания в client::bind_recv
_recv_callback = f;
, когда переданный параметр f
не относится к типу _recv_callback
?
Даже если вы можетеопределите оператор присвоения для _recv_callback
, который допускает различные типы для правой стороны, вы можете «потерять» некоторую информацию.В частности, после назначения вы больше не знаете, какой тип был f
.И что еще хуже, f
мог иметь некоторые дополнительные переменные-члены, которые вы не можете сохранить в _recv_callback
.
. Решение этих проблем состоит в том, чтобы сначала определить общий «базовый» (возможно, абстрактный) классразрешенный параметр f
для передачи client::bind_recv
.Затем вы используете полиморфизм для лечения разных случаев.Пример:
#include <memory>
class callback {
// Some purely virtual functions for a generic interface
virtual ~callback { }
};
class recv_callback : callback {
// Specific implementations of pure virtual members declared in callback
virtual recv_callback;
};
class client
{
public:
void bind_recv(callback *f)
{
_recv_callback.reset(f);
}
protected:
std::unique_ptr<callback> _recv_callback;
}
Передав указатель на client::bind_recv
, вы избегаете проблемы незнания того, как обрабатывать неизвестный тип f
: вам нужно передать уже выделенный объект.Также обратите внимание, что я использовал умный указатель для _recv_callback
, чтобы не допустить утечки памяти.