c++ - 如何使 C++ 编译时计算程序递归级别更深?
问题描述
我有一个程序可以在编译时计算 N 以下的所有素数。例如,如果我设置 N = 20,我会得到 {2, 3, 5, 7, 11, 13, 17, 19},如果 N = 10,我会得到 {2, 3, 5, 7}我试过 N = 1499,它工作,但不大于 1499。如果 N = 1500,那么“致命错误 C1202 递归类型或函数依赖上下文太复杂”会出来......
PS:我正在使用带有 c++17、调试模式和 X86 的 vs2019
有没有办法将 N 扩大到 10000 或更多?(对于 msvc 和 gcc)这是我的代码
#include <cstdlib>
#include <cstdio>
#include <utility>
static const int N = 1499;
constexpr bool IsPrime(int n)
{
if (n > 6)
{
if (n % 6 != 1 && n % 6 != 5)
{
return false;
}
for (int i = 5; i * i < n; ++i)
{
if (n % i == 0)
{
return false;
}
}
return true;
}
else if (n == 2 || n == 3 || n == 5)
{
return true;
}
else
{
return false;
}
}
template <size_t...V>
struct is_prime_t
{
bool is_prime[sizeof...(V)] = {
IsPrime(V)...
};
};
template <size_t...V>
constexpr is_prime_t <V...> GetIsPrime_T(std::index_sequence<V...>)
{
return is_prime_t<V...>();
};
static constexpr auto is_prime_list = GetIsPrime_T(std::make_index_sequence<N>());
constexpr auto GetNextPrime(int prime)
{
for (int i = prime - 1; i >= 0; --i)
{
if (is_prime_list.is_prime[i]) return i;
}
return 0;
}
template <size_t...V>
struct prime_list_t
{
size_t prime_list[sizeof...(V)] = {
V...
};
};
template <bool, size_t N, size_t... Primes>
struct prime_sequence_helper_with_checker;
template <size_t N, size_t... Primes>
struct prime_sequence_helper
{
typedef typename prime_sequence_helper_with_checker<IsPrime(N), N, Primes...>::type type;
};
template <size_t... Primes>
struct prime_sequence_helper<0, Primes...>
{
typedef typename prime_list_t<Primes...> type;
};
template <size_t N>
struct prime_sequence
{
typedef typename prime_sequence_helper<N>::type type;
};
template <bool, size_t N, size_t... Primes>
struct prime_sequence_helper_with_checker;
template <size_t N, size_t... Primes>
struct prime_sequence_helper_with_checker<true, N, Primes...>
{
//typedef typename prime_sequence_helper<N - 1, N, Primes...>::type type;
typedef typename prime_sequence_helper<GetNextPrime(N), N, Primes...>::type type;
};
template <size_t N, size_t... Primes>
struct prime_sequence_helper_with_checker<false, N, Primes...>
{
//typedef typename prime_sequence_helper<N - 1, Primes...>::type type;
typedef typename prime_sequence_helper<GetNextPrime(N), Primes...>::type type;
};
template <size_t N>
constexpr auto GetPrimeList_T()
{
return prime_sequence<N>::type();
}
int main()
{
constexpr auto prime_list = GetPrimeList_T<N>();
system("pause");
return 0;
}
解决方案
您可以通过...避免递归来避免太深的递归:
constexpr bool IsPrime(int n)
{
if (n > 6)
{
if (n % 6 != 1 && n % 6 != 5)
{
return false;
}
for (int i = 5; i * i < n; ++i)
{
if (n % i == 0)
{
return false;
}
}
return true;
}
else if (n == 2 || n == 3 || n == 5)
{
return true;
}
else
{
return false;
}
}
template <std::size_t... Is>
constexpr auto get_primes(std::index_sequence<Is...>)
{
constexpr auto res = [](){
constexpr bool is_prime[sizeof...(Is)] = { IsPrime(Is)... };
std::array<std::size_t, std::count(std::begin(is_prime), std::end(is_prime), true)> res{};
std::size_t index = 0;
for (std::size_t i = 0; i != sizeof...(Is); ++i) {
if (is_prime[i]) res[index++] = i;
}
return res;
}();
return res;
}
推荐阅读
- c# - 如何模拟返回void但修改传入的引用类型的方法?
- postgresql - PostgreSQL 错误:在不接受集合的上下文中调用的集合值函数
- angular - Angular Portal 未触发 ComponentPortal 的更改检测
- asp.net - 累积更新 KB4576947 或 KB4578974 后,HttpContext.Current 在 WebForms 应用程序中为空
- javascript - 返回一个 forkJoin rxJS 的元组
- react-native - 在 React Native 应用中实现 Java SDK
- python - 如何从 python 请求响应中访问某些项目?
- loops - 使用 while 循环重复 3 个小部件。飘飘然
- python - 根据来自另一个数据框的间隔将列添加到数据框
- java - 在 Toast 中获取 ratingbar 值