我有一个可变的类模板,它有一个嵌套的可变参数类模板。外部类模板有一个函数模板,它接受任意数量的参数,并返回一个inner类型的对象。我的问题是创建一个完全独立的函数,它将接受任何数量的内部类型的任何变体(并且只有内部类型),而不管外部类型的变体,同时仍然确保函数的可接受类型是嵌套成员只有那个外部类模板。不确定我是否充分解释了......这基本上就是我正在使用的内容:
template<typename... ArgsOuter> class Outer {
typedef Outer<ArgsOuter...> outer_t;
template<typename... ArgsInner> class Inner {
//static const outer_t* outer;
typedef outer_t outer;
Inner(const ArgsInner&... args_inner) {
//do stuff
}
};
/*
What's passed in here will be related to and will be a subset of
the types used to define the Outer class, but I'm not really
concerned about checking what's being passed in right now.
*/
template<typename... ArgsFunc>
make_inner(ArgsFunc... args_func) {
return Inner<ArgsFunc...> (args_func...);
}
};
struct ThingA : Outer<int, int, float> {
};
struct ThingB : Outer<int, string, int> {
};
struct ThingC : Outer<string, string, int, int> {
};
//struct ThingN : Outer<random types...> {}
//...meanwhile, over at main...
ThingA tA;
ThingB tB;
ThingC tC;
auto tA_inner = tA.make_inner(1, 1.1);
auto tB_inner = tB.make_inner(2, "foo");
auto tC_inner = tC.make_inner("bar", 2, "foobar");
//mystery_func() is the function I'm not sure how to define.
auto meatloaf = mystery_func(tA_inner, tB_inner, tC_inner);
任何人都有SFINAE或可变功能模板(或其他)解决方案吗?
答案 0 :(得分:2)
我认为这可能实际上是不可能的。你似乎想要的是做这样的事情的能力:
template < typename ... Args1, typename ... Args2, typename ... Args3>
?? mystery_func(Inner<Args1...>,Inner<Args2...>,Inner<Args3...>);
我认为你不能那样做。如果可以,那就是你的答案。
因为我怀疑你能做到这一点,你需要做的只是采取三种不同的类型,然后使用SFINAE来测试它们是Inner&lt;&gt; s,这就像使用基本的is_a一样简单元函数:
template < typename T > is_inner : boost::mpl::false_ {};
template < typename ... Pack > is_inner< Inner<Pack...> > : boost::mpl::true_ {};
答案 1 :(得分:1)
好吧,我并没有打算回答我自己的问题,但是我认为在过去的几天里我已经完全击败了我的头,想出这个问题......当然也学到了一些新的东西。方式(没有投诉)。这是一个丑小鸭(SFINAE +类型特征元函数+可变函数模板),但我运行了一些简单的测试,它似乎按预期工作。
//Use SFINAE to limit the types accepted
template<typename A, typename Result>
struct require_1_type { };
//Limit to Outer class
template<typename... ArgsA, typename Result>
struct require_1_type<Outer<ArgsA...>, Result> {
typedef Result type;
};
//Zero argument, base case for variadic function template.
void mystery_func() {}
//Recursive portion of variadic function template.
template<template<typename...> class First, typename... ArgsA, typename... Others>
typename std::enable_if<
std::is_same<
First<ArgsA...>
, typename require_1_type<
typename First<ArgsA...>::outer_t
, typename First<ArgsA...>::outer_t::template Inner<ArgsA...>
>::type
>::value
, some_lib::list<First<ArgsA...>, Others...>
>::type
mystery_func (First<ArgsA...> first, Others... others) {
mystery_func(others...);
return some_lib::make_list(first, others...);
}
我的目标是限制传入的类型,以及任何外部变体的内部变化。我认为这就是我所寻找的,至少看起来是这样。
我对这一切如何运作的理解如下,请在适当的时候更正:
传入一系列Inner
个对象。每个Inner
对象都有一个typedef引用其“Outer
类型。我们从参数包中剥离了一个Inner
对象,并检查typedef引用其“Outer
类型”以确保它与预期的Outer
类型匹配。如果匹配,则我们获取传入的第一个Inner
对象上使用的参数包,并将包传递到我们通过引用的Inner
typedef引用的Outer
模板到第一个Inner
。然后我们互相检查这两个Inner
,以确保它们是相同的。如果是,则启用该特定功能模板实例化。
可变参数函数模板本身只是递归地调用自身,以便参数包中的所有对象都对它们运行相同的检查,直到我们用完参数,该参数调用函数的空白版本。最后,每次递归都会调用(在本例中)一个将对象放在一个列表中的函数。
我不确定的一件事是编译器是否正在优化所有那些返回到无效的make_list调用,除了最后一个调用,这是由第一次调用mystery_func()
完成的,并且只有一个有目的的回报值。
无论如何,我们非常欢迎改进,评论和简化。