Хотя этот вопрос старый, я бы хотел найти способ сделать это.(Не совсем уверен в переносимости)
Насколько я понимаю, у вас есть классы B
и C
, которые наследуются от некоторого класса A
, и между ними существует только одна виртуальная функция.(Метод, который я здесь представляю, работает, если B
и C
также не связаны между собой.)
class A {
public:
virtual std::string hello() = 0;
};
class B : public A {
public:
virtual std::string hello() { return "B"; }
};
class C : public A {
public:
virtual std::string hello() { return "C"; }
};
И затем вы хотите взять B
в C
, затем вызвать hello
и получите "B"
.
Итак, есть способ создать разбавленную версию boost::any
, которая будет преобразовывать что угодно во все, что угодно:)
struct parent {};
template< typename T >
struct child : public parent {
child(T const& t): item(t){}
mutable T item;
};
template< typename T >
T& as(parent const & p) { return static_cast< child< T > const& >(p).item; }
Затем смешатьвсе вместе:
B b;
parent* p = new child< B >(b);
std::cout << as< C >(*p).hello() << std::endl;
// ==== OUTPUT ====
// B
Можно увидеть код в действии здесь .
Чтобы сделать шаг вперед, мы можем создать функцию, которая преобразует из одногонапиши другому, не давая заднему концу комара о том, что происходит между ними.
template< typename TO, typename FROM >
TO& convert(FROM const& from) {
parent* p = new child< FROM >(from);
return as< TO >(p);
};
Это можно запустить здесь .
(Понял, что я пропустилнаследование в этом примере ссылки на код, но после прочтения вопроса я думаю, что это действительно то, что было на самом деле желательно. Итак, чтобы посмотреть тест без наследования, перейдите здесь )
Какой-то другой кодчто я начал играть с этим, я подумал, что может помочь и некоторым ...
#include <iostream>
#include <string>
class B {
public:
virtual char hello() {return 'B';}
};
class C {
public:
virtual int hello() {return 65;}
};
struct parent {};
template< typename T >
struct child : public parent {
child(T const& t): item(t){}
mutable T item;
};
template< typename T >
T& as(parent const & p) { return static_cast< child< T > const& >(p).item; }
template< typename TO, typename FROM >
TO& convert(FROM const& from) {
parent* p = new child< FROM >(from);
return as< TO >(*p);
};
int main()
{
B b;
std::cout << convert< C, B >(b).hello() << std::endl;
C c;
std::cout << convert< B, C >(c).hello() << std::endl;
}
// ==== OUTPUT ====
// 66
// A
Разобраться, как сделать все это в функции преобразования:
template< typename TO, typename FROM >
TO& convert(FROM const& from) {
struct parent {};
struct child : public parent {
child(FROM const& t): item(t){}
mutable FROM item;
};
struct sibling : public parent {
sibling(TO const& t): item(t){}
mutable TO item;
};
parent* p = new child(from);
return static_cast< sibling const& >(*p).item;
};