元编程,阶乘,C++,boost
metaprogramming, factorial, C++, boost
需要计算从 1 到 k 的所有数字的阶乘,并使用 boost/mpl.
将它们保存在 mpl 容器中
存储在 range_c 中的此 nums 的范围。
困难在于我必须存储所有以前的值:
k! = (k-1)!*k
我认为我将在 mpl::vector_c 中存储以前的值,即每次迭代我将从源 range_c 中获取值并将其与包含在 [= 中的先前值 (k-1)!
相乘23=],但是我这段代码有很多错误:
namespace mpl = boost::mpl;
const int border = 10;
using namespace mpl;
typedef
range_c <int, 1, border>
Numbers;
typedef vector_c<int, 1> data;
typedef
mpl::transform
<
Numbers,
data,
push_back<data, multiplies <_, _>>,
back_inserter
<
mpl::vector <>
>
>::type
Factorials;
您可以使用以下内容:
namespace detail
{
// General computation of factorial
template <std::size_t N>
struct factorial :
std::integral_constant<std::size_t, N * factorial<N - 1>::value>
{
};
// special case for 0
template <>
struct factorial<0> : std::integral_constant<std::size_t, 1u>
{};
// helper to create the sequence of factorial value
template <typename T> struct factorial_seq_impl;
template <std::size_t...Is>
struct factorial_seq_impl<std::index_sequence<Is...>>{
using type = std::index_sequence<factorial<Is>::value...>;
};
}
// And finally
template <std::size_t N>
using factorial_seq =
typename detail::factorial_seq_impl<std::make_index_sequence<N>>::type;
static_assert(std::is_same<std::index_sequence<1, 1, 2, 6, 24>, factorial_seq<5>>::value, "");
阶乘 mpl 版本和向量中前 10 个结果的集合:
template <typename current, typename to, typename result>
struct calc :
eval_if< less_equal< current, to >,
calc< typename current::next, to, typename multiplies< result, current > >,
result
>::type
{};
template<typename value>
struct factorial :
calc<int_<1>, value, int_<1> >::type
{};
template <>
struct factorial<int_<0> > :
int_<1>::type
{};
template <>
struct factorial<int_<1> > :
int_<1>::type
{};
template <int value>
struct factorial_c :
factorial<int_<value> >::type
{};
struct factorial_collection_10 :
transform<
range_c<int, 0, 10>,
factorial<boost::mpl::_1>,
back_inserter<vector0<> >
>::type
{};
测试代码:
int main()
{
// get 5! value
std::cout << "5! = " << factorial_c<5>::value << std::endl;
// access 6th element of the factorial collection
std::cout << "6! = " << at<factorial_collection_10, int_<6> >::type::value << std::endl;
// copy factorial collection to std vector to check values at runtime
std::vector<int> factorialVec;
for_each< factorial_collection_10, boost::mpl::_1 >(boost::bind(static_cast<void(std::vector<int>::*)(const int&)>(&std::vector<int>::push_back), &factorialVec, boost::lambda::_1));
std::cout << "First 10 factorial numbers: " << std::endl;
for (std::size_t x = 0; x < factorialVec.size(); ++x)
std::cout << x << "! = " << factorialVec[x] << std::endl;
return 0;
}
输出:
5! = 120
6! = 720
First 10 factorial numbers:
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
在所有实现中,为从 1 开始的每个数字计算阶乘。在任务中,我需要通过与前一个阶乘相乘来计算每个下一个阶乘。这里正确的代码:
namespace mpl = boost::mpl;
using namespace mpl;
const int border = 15;
typedef range_c<int, 1, border> nums;
typedef vector<int_<1>> data;
typedef mpl::fold<
nums, data,
mpl::push_back<_1, mpl::multiplies<_2, back<_1>>>
>::type Factorials;
需要计算从 1 到 k 的所有数字的阶乘,并使用 boost/mpl.
将它们保存在 mpl 容器中存储在 range_c 中的此 nums 的范围。
困难在于我必须存储所有以前的值:
k! = (k-1)!*k
我认为我将在 mpl::vector_c 中存储以前的值,即每次迭代我将从源 range_c 中获取值并将其与包含在 [= 中的先前值 (k-1)!
相乘23=],但是我这段代码有很多错误:
namespace mpl = boost::mpl;
const int border = 10;
using namespace mpl;
typedef
range_c <int, 1, border>
Numbers;
typedef vector_c<int, 1> data;
typedef
mpl::transform
<
Numbers,
data,
push_back<data, multiplies <_, _>>,
back_inserter
<
mpl::vector <>
>
>::type
Factorials;
您可以使用以下内容:
namespace detail
{
// General computation of factorial
template <std::size_t N>
struct factorial :
std::integral_constant<std::size_t, N * factorial<N - 1>::value>
{
};
// special case for 0
template <>
struct factorial<0> : std::integral_constant<std::size_t, 1u>
{};
// helper to create the sequence of factorial value
template <typename T> struct factorial_seq_impl;
template <std::size_t...Is>
struct factorial_seq_impl<std::index_sequence<Is...>>{
using type = std::index_sequence<factorial<Is>::value...>;
};
}
// And finally
template <std::size_t N>
using factorial_seq =
typename detail::factorial_seq_impl<std::make_index_sequence<N>>::type;
static_assert(std::is_same<std::index_sequence<1, 1, 2, 6, 24>, factorial_seq<5>>::value, "");
阶乘 mpl 版本和向量中前 10 个结果的集合:
template <typename current, typename to, typename result>
struct calc :
eval_if< less_equal< current, to >,
calc< typename current::next, to, typename multiplies< result, current > >,
result
>::type
{};
template<typename value>
struct factorial :
calc<int_<1>, value, int_<1> >::type
{};
template <>
struct factorial<int_<0> > :
int_<1>::type
{};
template <>
struct factorial<int_<1> > :
int_<1>::type
{};
template <int value>
struct factorial_c :
factorial<int_<value> >::type
{};
struct factorial_collection_10 :
transform<
range_c<int, 0, 10>,
factorial<boost::mpl::_1>,
back_inserter<vector0<> >
>::type
{};
测试代码:
int main()
{
// get 5! value
std::cout << "5! = " << factorial_c<5>::value << std::endl;
// access 6th element of the factorial collection
std::cout << "6! = " << at<factorial_collection_10, int_<6> >::type::value << std::endl;
// copy factorial collection to std vector to check values at runtime
std::vector<int> factorialVec;
for_each< factorial_collection_10, boost::mpl::_1 >(boost::bind(static_cast<void(std::vector<int>::*)(const int&)>(&std::vector<int>::push_back), &factorialVec, boost::lambda::_1));
std::cout << "First 10 factorial numbers: " << std::endl;
for (std::size_t x = 0; x < factorialVec.size(); ++x)
std::cout << x << "! = " << factorialVec[x] << std::endl;
return 0;
}
输出:
5! = 120
6! = 720
First 10 factorial numbers:
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
在所有实现中,为从 1 开始的每个数字计算阶乘。在任务中,我需要通过与前一个阶乘相乘来计算每个下一个阶乘。这里正确的代码:
namespace mpl = boost::mpl;
using namespace mpl;
const int border = 15;
typedef range_c<int, 1, border> nums;
typedef vector<int_<1>> data;
typedef mpl::fold<
nums, data,
mpl::push_back<_1, mpl::multiplies<_2, back<_1>>>
>::type Factorials;