接受嵌套可变参数类模板作为函数模板的参数
我正在尝试创建一个函数模板,它将接受下面列出的两个(或更多)嵌套可变参数类模板作为参数,并将它们放入另一个将接受不同类型的数据结构中(我将使用对或元组)最有可能使用)。以下是类和子类,以及我的函数的用法(该函数在下面进一步定义):
template<typename... Args> struct Entity {
template<typename... InnerEntArgs> struct InnerEntity {
InnerEntity(InnerEntArgs... inner_ent_args) {
... //do stuff w/ InnerEntArgs pack
... //do stuff that makes Inner dependent on Outer's Args pack
}
};
};
struct ThingA : Entity<int, string> {
... //construct ThingA
};
struct ThingB : Entity<string, string> {
... //construct ThingB
};
auto foo = my_func(
ThingA::InnerEntity<int, int, int>(1, 2, 3)
, ThingB::InnerEntity<string, int>("bar", 1)
);
下面是我为该函数拼凑在一起的代码,它确实可以正常编译,但我不确定它是否已设置正确地起来。具体来说,我对 typename
和 ::template
在这种情况下如何让编译器满意,或者这个函数是否会按照我期望的方式运行有点模糊:
template<
typename... ArgsA, typename... ArgsAInner
, typename... ArgsB, typename... ArgsBInner
> auto my_func(
typename Entity<ArgsA...>::template InnerEntity<ArgsAInner...> A
, typename Entity<ArgsB...>::template InnerEntity<ArgsBInner...> B
) -> tuple<decltype(A), decltype(B)> {
return make_tuple(A, B);
}
我认为我很好地掌握了如何推导/推断参数包,以及如何auto
、decltype
和尾随返回类型正在做他们的事情,但如果我错了,请告诉我如何做。
另外,如果有人愿意演示此函数的可变参数版本,它可以接受任意数量的嵌套可变参数类模板并将它们放入合适的容器或数据结构中,那就太好了,但我主要关心的是完全理解typename
和 ::template
。提前致谢!
*如果我对这个标题的措辞不正确或者我混淆了术语,请解释。 :) 我是来学习的。
I'm trying to make a function template that will accept two (or more) of the nested variadic class templates listed below, as arguments, and put them into another data structure that will accept different types (pair or tuple is what I'll most likely use). Here are the classes and subclasses, along with the usage of my function (the function is defined farther below):
template<typename... Args> struct Entity {
template<typename... InnerEntArgs> struct InnerEntity {
InnerEntity(InnerEntArgs... inner_ent_args) {
... //do stuff w/ InnerEntArgs pack
... //do stuff that makes Inner dependent on Outer's Args pack
}
};
};
struct ThingA : Entity<int, string> {
... //construct ThingA
};
struct ThingB : Entity<string, string> {
... //construct ThingB
};
auto foo = my_func(
ThingA::InnerEntity<int, int, int>(1, 2, 3)
, ThingB::InnerEntity<string, int>("bar", 1)
);
Below is the code I cobbled together for the function, and it does compile fine, but I'm not sure if it is set up correctly. Specifically, I'm a little fuzzy on how typename
and ::template
are making the compiler happy in this context, or if this function will behave the way I'm expecting:
template<
typename... ArgsA, typename... ArgsAInner
, typename... ArgsB, typename... ArgsBInner
> auto my_func(
typename Entity<ArgsA...>::template InnerEntity<ArgsAInner...> A
, typename Entity<ArgsB...>::template InnerEntity<ArgsBInner...> B
) -> tuple<decltype(A), decltype(B)> {
return make_tuple(A, B);
}
I think I have a good grasp on how the parameter packs are being deduced/inferred, and how auto
, decltype
, and the trailing return type are doing their thing, but if I'm mistaken, please let me know how.
Also, if anyone cares to demonstrate a variadic version of this function that can accept any number of the nested variadic class templates and put them into a suitable container or data structure, that'd be great, but I'm primarily concerned with fully understanding typename
and ::template
. Thanks ahead of time!
*If I've worded this title incorrectly or I'm mixing up terms, please explain. :) I'm here to learn.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这将不起作用,因为 Entity::InnerEntity 是非推导上下文。意味着无法推导出
ArgsA...
和ArgsAInner...
,对于其他参数也是如此。这是因为,在编译器推导出Args
之前,它必须知道InnerEntity
属于什么类型,但要知道那个,它有推导Args
。您可以将此函数作为友元函数模板放入
Entity
中,并使其工作(只要两者都是同一模板的成员)。但上次我检查时,GCC 没有找到类模板中定义的友元函数。您还可以在
InnerEntity
中声明一些成员 typedef 来指定外部类的类型,并据此制定my_func
,以便 SFINAE 可以将其分类为非成员。当然,您不需要
template。 class AInner
事物,如果您不需要访问ArgsAInner
类型,如上面的my_func
所示。在这种情况下,您最好只接受typename AInner
并且编写更少的内容。 SFINAE 仍将确保只接受正确的内容。This will not work because
Entity<Args>::InnerEntity
is a non-deduced context. Means thatArgsA...
andArgsAInner...
cannot be deduced, likewise for the other parameter. This is because before the compiler can deduceArgs
, it has to know what typeInnerEntity
is a member of, but to know that, it has to deduceArgs
.You can put this function as a friend function template into
Entity<Args...>
and make it work as long as both are members of the same template. But last time I checked, GCC did not find friend functions defined in class templates.You could also declare some member typedef in
InnerEntity
that specifies the type of the outer class, and formulatemy_func
in terms of that, so that SFINAE can sort it out for non-members.Of course you don't need that
template<typename...> class AInner
thing if you don't need to access theArgsAInner
types, like in the abovemy_func
. In such a case you are better off just acceptingtypename AInner
and have less to write. The SFINAE will still make sure only the right thing is accepted.