请考虑以下代码:
#include <utility>
#include <tuple>
#include <map>
using namespace std;
enum class Type { D1, D2 };
struct Base {
virtual ~Base() = default;
virtual void doSth() = 0;
virtual Type getType() = 0;
};
struct D1 : Base {
Type getType() override { return Type::D1; }
void doSth() override { }
};
struct BaseExt : Base {
virtual void doSth2() = 0;
};
struct D2 : BaseExt {
Type getType() override { return Type::D2; }
void doSth() override { }
void doSth2() override {}
};
template <typename... Deriveds>
struct Manager
{
Manager(Deriveds... ds) {
_t = tuple<Deriveds...>(ds...);
// MAGIC NEEDED HERE TO POPULATE _mapOfTypes
}
void go(Type /* t */) {
// MAGIC NEEDED HERE
//std::get<_mapOfTypes[t]>(_t)->doSth();
}
void go2()
{
// std::get<_mapOfTypes[Type::D2]>(_t)->doSthD2(); // THIS IS WHAT I WANT TO ACHIEVE
}
tuple<Deriveds...> _t;
map<Type, int> _mapOfTypes;
};
int main()
{
D1 d1;
D2 d2;
Manager<D1,D2> m(d1,d2);
m.go(Type::D1);
m.go2();
}
此代码的链接: 的 https://wandbox.org/permlink/Jr5HJWimrL1wvZbs
我知道我可以在Manager中存储指向Base的指针,这很简单,oldschool。但是当我需要从BaseExt调用方法时(在go2方法中),我必须从Base *到BaseExt *进行static_cast。
我在想是否有可能以模板元编程的方式做到这一点。我想在没有任何强制转换的情况下调用方法doSth2。因为我有一个实现Base或Base2的具体类型的元组,并且我在编译时知道哪个对象在元组中的哪个位置,所以我想在不使用Base或Base2接口的情况下调用此对象。
我试过实现这个但是我卡住了。我知道我可以在一个元组中存储parameter_pack,然后使用index_sequence对这个元组进行操作。但是我填充_mapOfTypes时遇到问题。是否有可能做到这一点?