Skip to main content
Code Review

Return to Question

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

I wrote this code for an answer over on SO answer over on SO. I suspect it's possible to clean it up a bit, particularly the base-case specialization for FactorialArray, which is repetitive and contains odd bits (for instance: why double curly braces? because clang complains about un-braced subobject initializers otherwise...)

Any and all suggestions are appreciated. Note that Factorial is separate from FactorialArray for pedagogical clarity; I realize this makes the compile-time calculation O(N2) unless the compiler is clever enough to memoize it.

#include <iostream>
#include <cinttypes>
#include <array>
using std::uint64_t;
// Helper template that computes the factorial of one integer
template<uint64_t I> struct Factorial
{ static constexpr uint64_t value = I * Factorial<I-1>::value; };
template<> struct Factorial<0> { static constexpr uint64_t value = 1; };
// FactorialArray recursively assembles the desired array as a variadic
// template argument pack from a series of invocations of Factorial
template<uint64_t I, uint64_t... Values> struct FactorialArray
 : FactorialArray<I-1, Factorial<I>::value, Values...>
{};
// and in the base case, initializes a std::array with that pack
template<uint64_t... Values> struct FactorialArray<uint64_t(-1), Values...>
 : std::array<uint64_t, sizeof...(Values)>
{
 constexpr FactorialArray()
 : std::array<uint64_t, sizeof...(Values)> ({{Values...}})
 {}
};
int main()
{
 static FactorialArray<10> f;
 for (std::size_t i = 0; i < f.size(); i++)
 std::cout << i << "! = " << f[i] << '\n';
 return 0;
}

I wrote this code for an answer over on SO. I suspect it's possible to clean it up a bit, particularly the base-case specialization for FactorialArray, which is repetitive and contains odd bits (for instance: why double curly braces? because clang complains about un-braced subobject initializers otherwise...)

Any and all suggestions are appreciated. Note that Factorial is separate from FactorialArray for pedagogical clarity; I realize this makes the compile-time calculation O(N2) unless the compiler is clever enough to memoize it.

#include <iostream>
#include <cinttypes>
#include <array>
using std::uint64_t;
// Helper template that computes the factorial of one integer
template<uint64_t I> struct Factorial
{ static constexpr uint64_t value = I * Factorial<I-1>::value; };
template<> struct Factorial<0> { static constexpr uint64_t value = 1; };
// FactorialArray recursively assembles the desired array as a variadic
// template argument pack from a series of invocations of Factorial
template<uint64_t I, uint64_t... Values> struct FactorialArray
 : FactorialArray<I-1, Factorial<I>::value, Values...>
{};
// and in the base case, initializes a std::array with that pack
template<uint64_t... Values> struct FactorialArray<uint64_t(-1), Values...>
 : std::array<uint64_t, sizeof...(Values)>
{
 constexpr FactorialArray()
 : std::array<uint64_t, sizeof...(Values)> ({{Values...}})
 {}
};
int main()
{
 static FactorialArray<10> f;
 for (std::size_t i = 0; i < f.size(); i++)
 std::cout << i << "! = " << f[i] << '\n';
 return 0;
}

I wrote this code for an answer over on SO. I suspect it's possible to clean it up a bit, particularly the base-case specialization for FactorialArray, which is repetitive and contains odd bits (for instance: why double curly braces? because clang complains about un-braced subobject initializers otherwise...)

Any and all suggestions are appreciated. Note that Factorial is separate from FactorialArray for pedagogical clarity; I realize this makes the compile-time calculation O(N2) unless the compiler is clever enough to memoize it.

#include <iostream>
#include <cinttypes>
#include <array>
using std::uint64_t;
// Helper template that computes the factorial of one integer
template<uint64_t I> struct Factorial
{ static constexpr uint64_t value = I * Factorial<I-1>::value; };
template<> struct Factorial<0> { static constexpr uint64_t value = 1; };
// FactorialArray recursively assembles the desired array as a variadic
// template argument pack from a series of invocations of Factorial
template<uint64_t I, uint64_t... Values> struct FactorialArray
 : FactorialArray<I-1, Factorial<I>::value, Values...>
{};
// and in the base case, initializes a std::array with that pack
template<uint64_t... Values> struct FactorialArray<uint64_t(-1), Values...>
 : std::array<uint64_t, sizeof...(Values)>
{
 constexpr FactorialArray()
 : std::array<uint64_t, sizeof...(Values)> ({{Values...}})
 {}
};
int main()
{
 static FactorialArray<10> f;
 for (std::size_t i = 0; i < f.size(); i++)
 std::cout << i << "! = " << f[i] << '\n';
 return 0;
}
Source Link
zwol
  • 421
  • 3
  • 12

Initializing a std::array from a recursive template computation

I wrote this code for an answer over on SO. I suspect it's possible to clean it up a bit, particularly the base-case specialization for FactorialArray, which is repetitive and contains odd bits (for instance: why double curly braces? because clang complains about un-braced subobject initializers otherwise...)

Any and all suggestions are appreciated. Note that Factorial is separate from FactorialArray for pedagogical clarity; I realize this makes the compile-time calculation O(N2) unless the compiler is clever enough to memoize it.

#include <iostream>
#include <cinttypes>
#include <array>
using std::uint64_t;
// Helper template that computes the factorial of one integer
template<uint64_t I> struct Factorial
{ static constexpr uint64_t value = I * Factorial<I-1>::value; };
template<> struct Factorial<0> { static constexpr uint64_t value = 1; };
// FactorialArray recursively assembles the desired array as a variadic
// template argument pack from a series of invocations of Factorial
template<uint64_t I, uint64_t... Values> struct FactorialArray
 : FactorialArray<I-1, Factorial<I>::value, Values...>
{};
// and in the base case, initializes a std::array with that pack
template<uint64_t... Values> struct FactorialArray<uint64_t(-1), Values...>
 : std::array<uint64_t, sizeof...(Values)>
{
 constexpr FactorialArray()
 : std::array<uint64_t, sizeof...(Values)> ({{Values...}})
 {}
};
int main()
{
 static FactorialArray<10> f;
 for (std::size_t i = 0; i < f.size(); i++)
 std::cout << i << "! = " << f[i] << '\n';
 return 0;
}
lang-cpp

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