class Base
{
public:
virtual char* data() = 0;
};
template<typename T>
class Derived : public Base
{
public:
virtual char* data() { return reinterpret_cast<char*> m_data; }
private:
T* m_data;
};
template<typename T>
class Service
{ ... };
Base* obj = new Derived<int>();
Service srv<???>();
Можно ли, имея Base*, каким-то образом инстанцировать экземпляр Service его типом?
правда, так информацию о типе, с которым инстантиировался Derived можно только сохранить. Использовать ее для инстанциирования Service не получится (нужно, чтобы инфа о типе была доступна при компиляции, а ее компилятор-то и не знает)
Здравствуйте, andyp, Вы писали:
A>правда, так информацию о типе, с которым инстантиировался Derived можно только сохранить. Использовать ее для инстанциирования Service не получится (нужно, чтобы инфа о типе была доступна при компиляции, а ее компилятор-то и не знает)
Я в итоге сделал иначе, без таких извращений.
Просто интересно, можно ли с помощью "шаблонной магии" вытащить из Base тип и инстанцировать им другой шаблон?
Здравствуйте, lexer_lx, Вы писали:
_>Здравствуйте, andyp, Вы писали:
A>>правда, так информацию о типе, с которым инстантиировался Derived можно только сохранить. Использовать ее для инстанциирования Service не получится (нужно, чтобы инфа о типе была доступна при компиляции, а ее компилятор-то и не знает)
_>Я в итоге сделал иначе, без таких извращений. _>Просто интересно, можно ли с помощью "шаблонной магии" вытащить из Base тип и инстанцировать им другой шаблон?
Кроме того, что писал, посоветовать ничего не могу. Все вместе с фабрикой, которую советовали, выглядит как-то так:
#include <typeinfo>
class Base{
const std::type_info& _ti;
public:
Base(const std::type_info& ti):_ti(ti){}
const std::type_info& get_ti() const {return _ti;}
//остальной интерфейс
};
template<typename T>
class Derived : public Base
{
public:
Derived():Base(typeid(T)){}
};
class BaseService
{
public:
//интерфейс Service
};
template<typename T>
class Service: public BaseService
{
....
};
BaseService* service_factory(const Base* base_p)
{
if(typeid(int) == base_p->get_ti())
return new Service<int>();
else
return nullptr;
}
Здравствуйте, lexer_lx, Вы писали:
A>>правда, так информацию о типе, с которым инстантиировался Derived можно только сохранить. Использовать ее для инстанциирования Service не получится (нужно, чтобы инфа о типе была доступна при компиляции, а ее компилятор-то и не знает)
_>Я в итоге сделал иначе, без таких извращений. _>Просто интересно, можно ли с помощью "шаблонной магии" вытащить из Base тип и инстанцировать им другой шаблон?
нет, вытащить в компилтайме тип, который будет известен в рантайме нельзя.
Здравствуйте, night beast, Вы писали:
NB>нет, вытащить в компилтайме тип, который будет известен в рантайме нельзя.
Но можно хранить не указатель на базу, а некую обертку, в которой будет какая-то информация о типе, примерно как в умных указателях с делетером сделано.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Здравствуйте, Ops, Вы писали:
NB>>нет, вытащить в компилтайме тип, который будет известен в рантайме нельзя.
Ops>Но можно хранить не указатель на базу, а некую обертку, в которой будет какая-то информация о типе, примерно как в умных указателях с делетером сделано.
можно, но ТС хотел получить эту информацию в компилтайме.
наиболее близкий аналог, это boost::variant, но не зная исходную задачу советовать что-либо бесполезно.
Здравствуйте, lexer_lx, Вы писали:
_>Можно ли, имея Base*, каким-то образом инстанцировать экземпляр Service его типом?
Можно ли выполнить работу времени компиляции в рантайме?
Не в С++.
Можно ли спроектировать Base и Service так, чтобы Service параметризовалось классом Derived в рантайме?
Конечно, да.
Начиная от Паттернов Проектирования ООП, и кончая эмуляцией дженериков. Но это нужно смотреть на содержимое Service, чтобы предметно говорить.