嗨,有一个容器,其中的键是类型名,值是boost或std中的对象/实例???
我想要实现的是针对每种数据类型都有一个对象池,当我想要构造该对象时,我只想通过Key来获取。我已经有可用的代码,但是如果我使用更标准的东西,我会更开心。
目前我有这样的代码:
template<size_t index, size_t counter, typename T0, typename ...T>
struct PoolBuilderInternal
{
typedef typename boost::mpl::insert<
typename PoolBuilderInternal<index - 1, counter + 1, T...>::m
, boost::mpl::pair<T0, std::integral_constant<size_t, counter> > >::type m;
};
template<size_t counter, typename T0, typename ...T>
struct PoolBuilderInternal<1, counter, T0, T...>
{
typedef typename boost::mpl::map<boost::mpl::pair<T0, std::integral_constant<size_t, counter> > > m;
};
template<typename ...T>
struct Pools
{
std::tuple<
boost::object_pool<T>...> m_pools;
typedef typename PoolBuilderInternal<sizeof...(T), 0, T...>::m poolType;
template<typename T>
boost::object_pool<T>& GetPool()
{
return std::get< boost::mpl::at<poolType, T>::type::value>(m_pools);
}
};
Pools<int, std::string, int64_t> m_pools;
m_pools.Get<int>();
编辑:我想要的是一张编译时间图。您可以想象一个std :: tuple <>,但是某些索引std :: get <0,1,2> ...却不能通过键(?std :: tuple_map)
访问答案 0 :(得分:2)
如果池中的类型是唯一的,请使用c ++ 14 std::get< T >(std::tuple(s))
#include <iostream>
#include <string>
#include <tuple>
struct A
{
int value = 17;
};
int main()
{
auto t = std::make_tuple(1, std::string{"Foo"}, 3.14, A{});
std::cout << "(" << std::get<int>(t) << ", "
<< std::get<std::string>(t)
<< ", " << std::get<double>(t)
<< ", " << std::get<A>(t).value << ")\n";
}
答案 1 :(得分:0)
如果我正确地理解了这个问题(并且不确定我是否知道),那么您真正想要的是某种 class factory ,并且以各种形式,这是众所周知的设计模式,因为它允许工厂的用户构造其构造函数(实际上是类型,在涉及类层次结构时,常常是类型)是未知的或超出其范围的对象。
在此基础上,我谨向您提供以下概念验证代码。请注意,我匆忙将它们放在一起,可能不是最佳选择。我敢肯定,还有更多的可能,包括将参数传递给相关构造函数,并从调用站点传递到make_string()
和make_foo()
(例如factory [t_string] ("My string")
。我会在有空的时候研究一下,如果您对此帖子表现出任何兴趣。
好的,这是您的班级工厂。您应该能够将其应用于任何类型,包括增强类型。按照编码,当前需要在将工厂函数(例如make_string
)添加到映射时定义任何需要传递给相关对象的参数(这可能不理想)。这些工厂功能也可以是lambda。再次,我将在以后添加。
#include <functional>
#include <unordered_map>
#include <variant>
#include <iostream>
struct Foo
{
Foo (int x) : x (x) { }
int x;
};
enum ObjectType { t_string, t_foo }; // ...
using all_possible_types = std::variant <std::string, Foo>; // ...
static all_possible_types make_string (const std::string& s)
{
std::cout << "make_string " << s << "\n";
return all_possible_types (std::string (s));
}
static all_possible_types make_foo (int x)
{
std::cout << "make_foo " << x << "\n";
return all_possible_types (Foo (x));
}
// ...
int main()
{
std::unordered_map <ObjectType, std::function <all_possible_types ()>> factory;
factory.insert ({t_string, std::bind (make_string, "Initial string value")});
factory.insert ({t_foo, std::bind (make_foo, 42)});
// ...
all_possible_types variant_string = factory [t_string] ();
std::cout << std::get <std::string> (variant_string) << "\n\n";
all_possible_types variant_foo = factory [t_foo] ();
std::cout << std::get <Foo> (variant_foo).x << "\n";
}
输出:
make_string Initial string value
Initial string value
make_foo 42
42
正如我所说,现在看起来并不多,但稍后我会加以改善。同时,我建议您看一下它,以使您了解我在这里所做的事情。