不完全为整型的结构和枚举
Structs and enumerations with not-exactly-integral type
现在我知道以下是如何工作的:
template<std::uint8_t num>
struct factorial
{
static_assert(num <= 20, "Integer overflow!!");
enum { value = num * factorial<num - 1>::value };
};
template <>
struct factorial<0>
{
enum { value = 1 };
};
它在编译时使用递归计算数字的阶乘!
您可以这样调用此函数:std::cout << factorial<20>::value;
很漂亮,但一个enum
只能容纳整数类型(最多为std::uintmax_t
)。这意味着我们不能计算一个大于20的数的阶乘。
现在我已经编写了一个不错的bigint
小类,它删除了边界。
考虑以下内容:
template<std::uintmax_t num>
struct factorial
{
static bigint value()
{
bigint result("1");
for (bigint i("2"); i <= num; ++i)
result *= i;
return result;
}
};
这需要我这样称呼它:std::cout << factorial<99>::value();
。明显地因为这是一个函数。
我的问题是:有没有一种方法可以修改代码/函数,使其像第一个例子一样被调用,但仍然使用bigint
类,我不能把它放在enum
中。
首先,使用c++14,您可以将value()
转换为constexpr
:
template<std::uintmax_t num>
struct factorial
{
constexpr bigint value()
{
bigint result(1);
for (bigint i(2); i <= num; ++i)
result *= i;
return result;
}
};
int main()
{
static_assert(factorial<3>().value() == 6, "");
}
现在,如果你想用旧语法访问它,你可以用轻松地完成
template<std::uintmax_t num>
struct factorial
{
constexpr static bigint calc_value()
{
bigint result(1);
for (bigint i(2); i <= num; ++i)
result *= i;
return result;
}
constexpr static bigint value = calc_value();
};
...
static_assert(factorial<3>::value == 6, "");
为了举例说明,bigint
就是unsigned
。
但是,请注意,这对bigint
类提出了很大的要求,即它应该能够在编译时进行所有需要的计算,这可能会困难得多。然而,这显然是您的问题的内在要求。
UPD:刚刚注意到您的实际问题实际上并不是问编译时计算,而是问类似enum
的语法。但这更容易做到:
template<std::uintmax_t num>
struct factorial
{
static bigint calc_value() { /* same code */ }
static const bigint value;
};
template<std::uintmax_t num>
const bigint factorial<num>::value = factorial<num>::calc_value();
如果您要使用int
(或类似的)而不是std::uintmax_t
,这甚至是c++03兼容的。
相关文章:
- 访问在 C++ 结构中声明的枚举变量
- 带有枚举方向/类型的气泡排序结构数组
- 从 cin 获取 c++ 中结构中多个枚举的输入
- 在结构中使用枚举的值
- 创建结构作为枚举类成员
- 在 C++ 中使用枚举而不是结构进行标记调度
- 为什么要在结构中放置枚举,然后使用 typedef 名称?
- std::映射键作为模板化结构与枚举成员
- 与常规枚举相比,c++ 枚举结构的大小更大吗?
- 枚举范围无法通过 C++ 中的类中的结构访问
- 如何编写一个错误结构,该结构可以包含不同的强键枚举作为错误代码
- 用枚举场和STL容器解析结构,并使用增强精神/融合轻松
- 在容器内过度对齐的结构和枚举之间的C 差异
- 当枚举器列表项的标识符已是结构的成员时,如何使用枚举器列表项
- 从匿名结构访问枚举条目
- 模板结构结合枚举
- 模板结构的多个声明,用于获取枚举,描述模板类型
- 如何定义别名以通过结构访问枚举类成员
- 在c++中创建字符串的枚举/结构体
- 无法访问常量静态标准::映射枚举结构