Допустим, у меня есть класс интерфейса и шаблонный подкласс
struct IPort {
virtual bool can_connect_to(std::shared_ptr<IPort> p) = 0;
std::shared_ptr<IPort> receiver;
};
template <class T>
struct Port : IPort {
bool can_connect_to(std::shared_ptr<IPort> p) override {
// what goes here?
}
void send(T* t) {
auto p = std::static_pointer_cast<Port>(receiver);
p->on_recv(t);
}
std::function<void(T*)> on_recv;
};
Параметр шаблона может быть любого типа.У меня есть несколько базовых типов (Base
и Other
ниже), а также производный тип (Derived
).
struct Base {
virtual const char* get_data() = 0;
virtual size_t get_size() = 0;
};
struct Derived : public Base {
std::string str;
const char* get_data() override { return str.c_str(); }
size_t get_size() override { return str.size(); }
};
struct Other {
double x, y, z;
};
В идеале я должен иметь возможность отправлять производный тип из порта вдругой порт, который принимает базовый тип (например, Port<Derived>
должен иметь возможность подключения к Port<Base>
).С другой стороны, я не должен иметь возможность отправлять несовместимые типы (Port<Other>
не должен иметь возможность подключаться к Port<Base>
).
auto sender1 = std::make_shared<Port<Derived>>();
auto sender2 = std::make_shared<Port<Other>>();
auto receiver = std::make_shared<Port<Base>>([](Base* t) {
// do something with t
});
sender1->can_connect_to(receiver); // should return true
sender2->can_connect_to(receiver); // should return false
Что можно вставить в can_connect_to
, чтобы убедиться, чтопереданный порт имеет шаблонный тип, который является суперклассом шаблона отправляющего порта?
Кроме того, почему работает static_pointer_cast
in send
?Кажется, что это правильно, но я не понимаю, как это вообще допустимо в c ++, поскольку нет параметра шаблона для Port
.