我有一个类Foo需要有可变数量的模板参数,但是这些参数需要是某种泛型类型,而不是完全随意的。 例如
template < int I, typename T> struct Arg; using type1 = Foo<Arg<3, double>>; using type2 = Foo<Arg<1, int>, Arg<7, float>, Arg<1, int>>;我想知道什么是实现这一目标的最佳方法。 我想我需要先从简单的可变模板开始
template < typename ...T > class Foo;从那里,我可以按照递归的道路
template < int I, typename T, typename ...Others> template Foo<Arg<I, T>, Others...> { ... };但是对另一个问题的这个答案的阅读让我怀疑我对可变参数模板的了解以及有时可以避免递归。
我的问题是,事实是模板参数预期是相对刚性的格式,这使得Foo的局部特化不会递归,并且可以有效地处理Foo<Arg<...>,Arg<...>,...>形式的所有Foo Foo<Arg<...>,Arg<...>,...> ?
I have a class Foo that needs to have a variable number of template arguments, but these arguments need to be of a certain generic type, as opposed to being completely arbitrary. E.g
template < int I, typename T> struct Arg; using type1 = Foo<Arg<3, double>>; using type2 = Foo<Arg<1, int>, Arg<7, float>, Arg<1, int>>;I am wondering what would be the best way to achieve this. I guess I need to start first with a plain variadic template
template < typename ...T > class Foo;From there, I could follow the recursive road
template < int I, typename T, typename ...Others> template Foo<Arg<I, T>, Others...> { ... };but the reading of this answer to another question left me wonder about my knowledge of variadic templates and how recursion can sometimes be avoided.
My question is, does the fact that the template arguments are expected to be in a relatively rigid format enable a partial specialization of Foo that would not be recursive, and that would effectively handle all Foos of the form Foo<Arg<...>,Arg<...>,...>?
最满意答案
这工作:
#include <iostream> template <int i, typename T> struct Arg; template <typename ...T> class Foo; template <int ...Is, typename ...Ts> class Foo<Arg<Is, Ts>...> { public: static constexpr unsigned int N = sizeof...(Is); }; int main() { using type2 = Foo<Arg<1, int>, Arg<7, float>, Arg<1, int>>; std::cout << type2::N << "\n"; }尽管以这种形式使用模板参数可能会也可能不容易,但取决于您想要对它们做什么。
This works:
#include <iostream> template <int i, typename T> struct Arg; template <typename ...T> class Foo; template <int ...Is, typename ...Ts> class Foo<Arg<Is, Ts>...> { public: static constexpr unsigned int N = sizeof...(Is); }; int main() { using type2 = Foo<Arg<1, int>, Arg<7, float>, Arg<1, int>>; std::cout << type2::N << "\n"; }Though it might or might not be easy or convenient to use the template arguments in that form, depending on what you want to do with them.
更多推荐
发布评论