Revision 5cd17fad-a118-416e-aef5-901b73aab89c - Code Review Stack Exchange

From a [previous question](http://codereview.stackexchange.com/q/45310/507) I got [an answer](http://codereview.stackexchange.com/a/45334/507) that included some template magic (that to be blunt was mind-boggling (as I could not understand it)).

So I have been trying to achieve the same results (because trying helps me learn). 
To make sure I have learn correctly I am putting it here for comment. Hopefully it will also help somebody else (and you never know it may encourage me to write a blog post about it).

Template based ranges (I am sure it has been done to death).

The idea you provide a range that expanded by the template to make writing code easier. So the code I use to test it is working correctly.

 template<typename>
 struct printNumberRange;
 
 // Only a specialization for my range is implemented.
 template<int... N>
 struct printNumberRange<Sizes<N...>>
 {
 static void call()
 {
 std::vector<int> v {N...};
 std::copy(std::begin(v), std::end(v), std::ostream_iterator<int>(std::cout, "\n"));
 }
 };
 
 // Function to deduce the arguments and
 // Call the print correctly.
 template<int S, int E>
 void printRange()
 {
 print<typename Range<S,E>::type>::call();
 }

 int main()
 {
 // Print the range using a template
 printRange<3,8>();
 }


###Version 1

The template code I started with:

 template<int... N>
 struct Sizes
 {
 typedef Sizes<N...> type;
 };
 
 template<int C, int P, int... N>
 struct GetRange
 {
 typedef typename GetRange<C-1, P+1, N..., P>::type type;
 };
 template<int P, int... N>
 struct GetRange<0, P, N...>
 {
 typedef typename Sizes<N..., P>::type type;
 };
 
 template<int S, int E>
 struct Range
 {
 typedef typename GetRange<E-S, S>::type type;
 };

But it seems the trend nowadays is to use inheritance to get rid of the ugly `typedef typename ....` at each level:

###Version 2

This should be exactly the same. 
But we use inheritance to get the type of the terminal class in the recursion. Personally I find this much harder to read than the previous version. But it is more compact.

 template<int... N>
 struct Sizes
 {
 typedef Sizes<N...> type;
 };
 
 template<int C, int P, int... N>
 struct GetRange: GetRange<C-1, P+1, N..., P>
 {};
 template<int P, int... N>
 struct GetRange<0, P, N...>: Sizes<N...>
 {};
 
 template<int S, int E>
 struct Range: GetRange<E-S+1, S>
 {};

I can specialize `printNumberRange` to take a range directly.

 template<int S, int E>
 struct printNumberRange<Range<S, E>>:
 printNumberRange<typename Range<S,E>::type> // Inherits from the version
 {}; // That takes a Sizes<int...>

Then the print becomes:

 int main()
 {
 printNumberRange<Range<4,18>>::call();
 }

Any comments on the Range stuff or the test harness welcome.

AltStyle によって変換されたページ (->オリジナル) /