我有一个模板类template<typename T> class TplObject
。我需要一种静态结构的数组,其中索引为typename T
. 我可以做这样的事情:
array.add<Type1>(); // New Object of type TplObject<Type1> was added
TplObject<Type1> obj = array.get<Type1>();
有没有这样的结构,mb in boost?如果没有,你能建议如何制作吗?
我有一个模板类template<typename T> class TplObject
。我需要一种静态结构的数组,其中索引为typename T
. 我可以做这样的事情:
array.add<Type1>(); // New Object of type TplObject<Type1> was added
TplObject<Type1> obj = array.get<Type1>();
有没有这样的结构,mb in boost?如果没有,你能建议如何制作吗?
所以这是一个做这样的事情的例子。我采用类型列表来实例化模板,用它们实例化模板,将实例存储在元组中,并提供基于类型的查找get
方法。
#include <type_traits>
#include <utility>
#include <tuple>
// Metaprogramming boilerplate:
template<typename... Ts> struct type_list {};
template<typename T, typename list, typename=void> struct index_in;
template<typename T, typename T0, typename... Ts>
struct index_in<T, type_list<T0, Ts...>, typename std::enable_if<std::is_same<T,T0>::value>::type>
{
enum { value = 0 };
};
template<typename T, typename T0, typename... Ts>
struct index_in<T, type_list<T0, Ts...>, typename std::enable_if<!std::is_same<T,T0>::value>::type>
{
enum { value = index_in<T, type_list<Ts...>>::value+1 };
};
// The tuple of instantiations of Factory:
template<template<typename>class Factory, typename... Ts>
struct PolytypeFactory {
std::tuple< Factory<Ts>... > data;
template<typename T>
Factory<T>& get() {
return std::get< index_in< T, type_list<Ts...> >::value >( data );
}
template<typename T>
Factory<T> const& get() const {
return std::get< index_in< T, type_list<Ts...> >::value >( data );
}
};
// a test factory, that creates an instance of T from the constant 100.5:
template<typename T> struct maker100_5 { T operator()() const { return T(100.5); } };
// test code, where I create 100.5 as an int, double and char, then print them:
#include <iostream>
int main() {
PolytypeFactory<maker100_5, int, double, char> factory;
std::cout << factory.get<int>()() << "," << factory.get<double>()() << "," << factory.get<char>()() << "\n";
}
PolytypeFactory
如果需要,您可以通过使用boost::optional
、存储指向的指针Factory<Ts>
并允许某人new
通过类似的方法传入版本get()
,或者变得非常花哨并进行就地构造,来推迟构建内容。
您可能正在寻找std::type_index
. 结合std::shared_ptr
,以下内容可能会帮助您入门:
class typemap
{
std::map<std::type_index, std::shared_ptr<void>> map_;
public:
template<typename T>
void set(std::shared_ptr<T> obj)
{
map_[std::type_index(typeid(T))] = obj;
}
template<typename T, typename... Args>
void emplace(Args&&... args)
{
this->set(std::make_shared<T>(std::forward<Args>(args)...));
}
template<typename T>
std::shared_ptr<T> get()
{
return std::static_pointer_cast<T>(map_[std::type_index(typeid(T))]);
}
};
此示例可以保存每种类型的一个对象,使用它执行以下操作:
typemap m;
// set
m.set( std::make_shared< int >( 42 ) );
m.set( std::make_shared< MyClass >() );
m.set( std::make_shared< std::vector<double> >() );
// or use emplace
m.emplace<int>( 42 );
m.emplace< MyClass >();
m.emplace< std::vector<double> >();
// access
int douglas = *m.get< int >();
m.get< MyClass >()->adams();
m.get< std::vector<double> >()->push_back( 3.141592 );