使用 MPL 创建所有模板排列
我有以下模板化类结构
struct TraitA{};
struct TraitB{};
template<typename trait>
struct FunctionalityA{};
template<typename trait>
struct FunctionalityB{};
template<typename Func>
struct FuncUserA{};
template<typename Func>
struct FuncUserB{};
template<typename fuser>
struct Host{};
Host 类现在可以具有以下类型。
typedef Host<FuncUserA<FunctionalityA<TraitA> > > Host1_t;
typedef Host<FuncUserA<FunctionalityA<TraitB> > > Host2_t;
typedef Host<FuncUserA<FunctionalityB<TraitA> > > Host3_t;
typedef Host<FuncUserA<FunctionalityB<TraitB> > > Host4_t;
typedef Host<FuncUserB<FunctionalityA<TraitA> > > Host5_t;
typedef Host<FuncUserB<FunctionalityA<TraitB> > > Host6_t;
typedef Host<FuncUserB<FunctionalityB<TraitA> > > Host7_t;
typedef Host<FuncUserB<FunctionalityB<TraitB> > > Host8_t;
有没有办法用 boost::mpl 创建类型列表?目前我什至不知道从哪里开始。 我的目标是拥有这样的功能:
template<class T>
T* getHost()
{
typedef boost::mpl::find<HostVector, T>::type MplIter;
return new MplIter;
}
Is this possible with boost::mpl?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好的,这是一些实现。它是相当特别的,显然可以将其抽象为一系列 lambda 函数序列,但我更喜欢保持这个直截了当。评论和测试在里面:
预期的输出应该是:
Ok here is some implementation. It is rather ad-hoc, one could obviously abstract it to take a sequence of sequence of lambda function, but I preferred keeping this one straight. Comments and tests are inside:
The expected output should be :
简介
我的答案试图成为 C++11 用户的首选答案。
Joel Falcou 的答案非常适合旧标准,但 C++11 的
参数包通常会使 boost 类型序列变得过时。此外,我认为在这种情况下,小猪支持模板比使用 boost::lambda 更好。
实际上,我的解决方案根本不使用任何包含内容,除了我将从此处获取的笛卡尔积模板,因为它不在标准中图书馆。
使用当前最新的功能(从 C++11 开始)允许编写具有以下功能的解决方案:
不同的模板解释:
expand_pack
执行其参数。这允许使用省略号重复运行时代码。示例:expand_pack(new T{}...)
。 谁知道这个成语的名字?wrap_template_as_type
搭载了一个模板,因此可以在需要类型的地方使用它。也许这个习惯用法被称为模板重新绑定或后期模板绑定。我不知道,所以我在这里发布了这个问题。示例:
wrap_template_as_type
和相反的
wrapper::unwrapp
type_list
没有数据、响铃和 Wissels 的元组。template_list
一个模板,它接受模板列表并返回一个 type_list,其中原始模板支持在包装器中。make_host_type
将A, B, C, D
转换为A>>
all_hosts
获取 Host 类型的元组,并为输入元组中的每个元素添加一个 Host。完整示例
请注意,
#include http://...
必须替换为链接内容请注意,MSVC 不理解 PRETTY_FUNCTION,而是理解 FUNCDNAME我认为
输出是:(如果您使用 MSVC,请将 PRETTY_FUNCTION 替换为其他内容)
Introduction
My answer tries to be the prefered one for C++11 users.
Joel Falcou's answer is great for the older standard but C++11's
parameter packs often make boost type sequences obsolete. Furthermore I think piggy backing templates is better in this case than using
boost::lambda
.Actually my solution uses no includes at all except the Cartesian product template which I will take from here as it is not in the standard library.
Using the currently newest features (as of C++11) allows coding a solution that:
The different templates explained:
expand_pack
executes its parameters. This allowes to repeat runtime code using ellipsis. Example:expand_pack(new T{}...)
. Anyone knows the name of this idiom?wrap_template_as_type
piggy backs a template so it can be used where a type is expected. Maybe this idiom is called template rebinding or late template binding.I do not know so I posted this question here. Examples:
wrap_template_as_type<map>
and the oppositewrapper::unwrapp<int, string>
type_list
a tuple without data, bells and wissels.template_list
a template that takes a list of templates and returns a type_list with the original templates piggy backed in a wrapper.make_host_type
convertsA, B, C, D
intoA<B<C<D>>>
all_hosts
gets a tuple of Host types and news one Host for each element in the input tuple.Full Example
Note that
#include http://...
must be replaced with the linked contentNote that MSVC does not understand PRETTY_FUNCTION but FUNCDNAME I think
Output is: (If you use MSVC replace PRETTY_FUNCTION with something else)