Ваш интерфейс действительно странный, он запрашивает метод, который не должен быть реализован.
У нас нет нескольких динамических c отправок, кроме std::visit
из std::variant
.
Таким образом, может помочь следующее:
using V = std::variant<A, B, C>;
int f(const V& v1, const V& v2) {
struct {
template <typename T1, typename T2>
int operator()(const T& t1, const T2& t2) const { throw runtime_error(""); };
int operator()(const A& a1, const A& a2) const { return a1.a + a2.a; };
int operator()(const B& b1, const B& b2) const { return b1.b1*b1.b1 + b1.b2*b1.b2 + b2.b1*b2.b1 + b2.b2*b2.b2; };
int operator()(const C& c1, const C& c2) const { return c1.c * c2.c; };
} visitor;
return std::visit(visitor, v1, v2);
}
или сохранение вашей иерархии:
using CV = std::variant<const A*, const B*, const C*>;
class I
{
public:
virtual ~I() = default;
virtual CV asVariant() const = 0;
};
class A: public I{
public:
A(int a) : a(a) {}
CV asVariant() const override { return this; }
friend int f (const A& a1, const A& a2) { /*logic here*/ return a1.a + a2.a; }
int a;
};
class B: public I{
public:
B(int b1, int b2) : b1(b1), b2(b2) {}
CV asVariant() const override { return this; }
friend int f (const B& b1, const B& b2) {
/*logic here*/ return b1.b1*b1.b1 + b1.b2*b1.b2 + b2.b1*b2.b1 + b2.b2*b2.b2;
}
private:
int b1;
int b2;
};
int f(const I& i1, const I& &2) {
struct {
template <typename T1, typename T2>
int operator()(const T1*, const T2*) const { throw runtime_error(""); };
template <typename T>
int operator()(const T* t1, const T* t2) const { return f(*t1, *t2); };
} visitor;
return std::visit(visitor, i1.AsVariant(), i2.AsVariant());
}