2016-04-26 3 views
1

Рассмотрим этот кодЗначение для типа отображения времени выполнения

enum Types 
{ 
    t1, 
    t2 
}; 

struct Base 
{ 
    Types typeTag; 
    Base(Types t) : typeTag(t){} 
}; 

template<typename T> 
struct Derived : Base 
{ 
    using Base::Base; 
    T makeT() { return T(); } 
}; 

int main() 
{ 
    Base *b = new Derived<std::string>(t1); 
    auto d = getDerivedByTag(b); // How ?? 
    d->makeT(); 
    return 0; 
} 

Можно ли восстановить Производный тип параметра по значению Base :: typeTag во время выполнения? Очевидно, что требуется некоторое внешнее предварительно подготовленное сопоставление, но я не могу точно определить его.

ответ

0

Что вы хотите, это в основном reflection, который еще не поддерживается в C++. Есть способы имитировать это или работать вокруг него, но они часто многословны и не изящны. Я бы предложил пересмотреть ваш дизайн, особенно ваше использование auto. Он не должен заменять «любой тип», как вы, кажется, подразумеваете своим кодом. Это означает упрощение кода, когда фактический тип длинный или запутанный (часто бывает с шаблонами), вложенные и т. Д. Не когда вы не знаете тип! Потому что тогда вы не можете его использовать, можете ли вы.

Так что вам нужно будет сделать так или иначе, прямо и непосредственно направить на это сообщение typeTag. В качестве альтернативы вам нужно будет использовать полиморфизм, используя напрямую Base (вызывающие виртуальные методы распространяются на Derived). Для союзов типов вы можете использовать boost::variant (если вам все равно, какой тип аргумента шаблона Derived) или какой-либо другой альтернативы рамочной/библиотеки, например QVariant в Qt.

0

Я не уверен, что мое понимание верное.

#include "iostream" 
enum Types 
{ 
    t1, 
    t2 
}; 

template<typename T> 
struct Base 
{ 
    typedef T DerivedType; 
    Types typeTag; 
    Base(Types t) : typeTag(t){} 
    DerivedType* operator()() { 
     return static_cast<DerivedType*>(this); 
    } 
}; 

template<typename T> 
struct Derived : Base<Derived<T>> 
{ 
    Derived(Types t): Base<Derived<T>>(t) {} 
    T makeT() { return T(); } 
}; 

int main() 
{ 
    Base<Derived<std::string>> *b = new Derived<std::string>(t1); 
    auto d = (*b)(); 
    d->makeT(); 
    return 0; 
} 

https://godbolt.org/g/uBsFD8

Моя реализация не имеет ничего общего с typeTag.

Возможно, вы имели в виду getDerivedByTag(b->typeTag), а не getDerivedByTag(b)?

Смежные вопросы