C++:模板元编程中的条件
C++: Conditionals in template meta programming
我正在实现一个程序,该程序使用 C++ 模板元编程从编译时已知的给定数字 NUMBER
生成下一个素数。但是,我目前被卡住了,因为我的模板中需要一个条件值。所以我正在寻找类似 C++ 中等效的三元运算符的东西。
我目前的做法:
#include <iostream>
#ifndef NUMBER
#define NUMBER 6
#endif
template <int P, int K = P - 1>
struct is_prime
{
enum { value = P % K != 0 && is_prime<P, K - 1>::value };
};
template <int P>
struct is_prime<P, 1>
{
enum { value = 1 };
};
template<int P, bool B = is_prime<P>::value>
struct next_prime
{
// This doesn't work
enum { value = ( B ? P : next_prime<P+1>::value )};
};
int main(int argc, char** argv)
{
std::cout << "next prime >= " << NUMBER << ": " << next_prime<NUMBER>::value << std::endl;
return 0;
}
使用 g++
编译时,会导致错误:
In instantiation of ‘struct is_prime<503, 4>’:
recursively required from ‘struct is_prime<503, 501>’
recursively required from ‘struct next_prime<3, true>’
required from ‘struct next_prime<2>’
fatal error: template instantiation depth exceeds maximum of 1000 (use ‘-ftemplate-depth=’ to increase the maximum)
有没有不使用 C++ 11 的好方法?
通常我看到这类问题通过专业化解决
template<int P, bool B = is_prime<P>::value>
struct next_prime
{ enum { value = next_prime<P+1>::value }; };
template <int P>
struct next_prime<P, true>
{ enum { value = P }; };
如果您可以使用 C++11 或更新版本,而不是定义 value
,我建议从 std::integral_constant
继承
// std::bool_constant<boolValue> is available starting from C++17;
// in C++11/C++14 you can use std::integral_constant<bool, boolValue>
template <int P, int K = P - 1>
struct is_prime
: public std::bool_constant<P%K && (not is_prime<P, K-1>::value)>
{ };
template<int P>
struct is_prime<P, 2> : public std::bool_constant<P%2>
{ };
template<int K>
struct is_prime<2, K> : public std::true_type
{ };
template<int P, bool B = is_prime<P>::value>
struct next_prime : public next_prime<P+1>
{ };
template <int P>
struct next_prime<P, true> : public std::integral_constant<int, P>
{ };
我正在实现一个程序,该程序使用 C++ 模板元编程从编译时已知的给定数字 NUMBER
生成下一个素数。但是,我目前被卡住了,因为我的模板中需要一个条件值。所以我正在寻找类似 C++ 中等效的三元运算符的东西。
我目前的做法:
#include <iostream>
#ifndef NUMBER
#define NUMBER 6
#endif
template <int P, int K = P - 1>
struct is_prime
{
enum { value = P % K != 0 && is_prime<P, K - 1>::value };
};
template <int P>
struct is_prime<P, 1>
{
enum { value = 1 };
};
template<int P, bool B = is_prime<P>::value>
struct next_prime
{
// This doesn't work
enum { value = ( B ? P : next_prime<P+1>::value )};
};
int main(int argc, char** argv)
{
std::cout << "next prime >= " << NUMBER << ": " << next_prime<NUMBER>::value << std::endl;
return 0;
}
使用 g++
编译时,会导致错误:
In instantiation of ‘struct is_prime<503, 4>’:
recursively required from ‘struct is_prime<503, 501>’
recursively required from ‘struct next_prime<3, true>’
required from ‘struct next_prime<2>’
fatal error: template instantiation depth exceeds maximum of 1000 (use ‘-ftemplate-depth=’ to increase the maximum)
有没有不使用 C++ 11 的好方法?
通常我看到这类问题通过专业化解决
template<int P, bool B = is_prime<P>::value>
struct next_prime
{ enum { value = next_prime<P+1>::value }; };
template <int P>
struct next_prime<P, true>
{ enum { value = P }; };
如果您可以使用 C++11 或更新版本,而不是定义 value
,我建议从 std::integral_constant
// std::bool_constant<boolValue> is available starting from C++17;
// in C++11/C++14 you can use std::integral_constant<bool, boolValue>
template <int P, int K = P - 1>
struct is_prime
: public std::bool_constant<P%K && (not is_prime<P, K-1>::value)>
{ };
template<int P>
struct is_prime<P, 2> : public std::bool_constant<P%2>
{ };
template<int K>
struct is_prime<2, K> : public std::true_type
{ };
template<int P, bool B = is_prime<P>::value>
struct next_prime : public next_prime<P+1>
{ };
template <int P>
struct next_prime<P, true> : public std::integral_constant<int, P>
{ };