递归推导缺少的模板专用化的值类型
Deduce value type for missing template specializations recursively
我现在有一个模板,它从作为参数存储的位数推断出一个具体类型:
template<unsigned char BITS>
struct Register {
using type = unsigned long;
};
template<>
struct Register<0> {
using type = void;
};
template<>
struct Register<8> {
using type = unsigned char;
};
template<>
struct Register<16> {
using type = unsigned short;
};
template<>
struct Register<32> {
using type = unsigned long;
};
是否可以扩展此模板,以便对于给定数量的位,它会自动推断下一个更高专业化的类型?这意味着:
- 注册<1..8> 导致专业化注册<8> Register<<li>9..16> 实际使用 Register<16> 和
- 注册<17..32>导致注册<32>。
我想到了像寄存器这样的解决方案是推断寄存器类型。但我不确定这是否是正确的方法,是否可以做到这一点。
但是,对于所有值>=33,它应该推断出类型 void 或 Register<0>。
例:
Register<4>::type value; // Register<8> will be used
Register<33>::type value = 1; // Compile error -> type is void
这可行吗?
首先,您需要引入一个定义递归的基本模板:
template< int N > struct impl_Int
{
using type = impl_Int<N+1>::type;
};
接下来,为固定大小定义专用化:
const int impl_CHAR = sizeof(signed char) != sizeof(short)
? sizeof(signed char) * CHAR_BIT
: INT_MIN;
template<> struct Register<impl_CHAR>
{
using type = char;
};
const int impl_SHORT = sizeof(short) != sizeof(int)
? sizeof(short) * CHAR_BIT
: INT_MIN + 1;
template<> struct Register<impl_SHORT>
{
using type = short;
};
const int impl_INT = sizeof(int) != sizeof(long)
? sizeof(int) * CHAR_BIT
: INT_MIN + 2;
template<> struct Register<impl_INT>
{
using type = int;
};
const int impl_LONG = sizeof(long) * CHAR_BIT;
template<> struct Register<impl_LONG>
{
using type = long;
};
最后,定义终止专用化:
template<> struct Register<INT_MAX>
{
using type = void;
};
有关实时示例,请参阅此处。
对于生产实现,您可能会将这些常量值隐藏在 impl
命名空间中,然后编写:
template <int N>
using Register = impl::Register<N>;
另请注意,您可以通过使用 C++11 固定宽度整数并对其大小进行硬编码来简化此操作。这将消除对常量的需求:
#include <climits>
#include <cstdint>
template< int N > struct Register
{
using type = typename Register<N+1>::type;
};
template<> struct Register<8>
{
using type = std::int8_t;
};
template<> struct Register<16>
{
using type = std::int16_t;
};
template<> struct Register<32>
{
using type = std::int32_t;
};
template<> struct Register<64>
{
using type = void;
};
int main() {
using T1 = Register<3>::type;
using T2 = Register<35>::type;
T1 v1;
T2 v2; // This line fails to compile: T2 is void.
}
现场示例
相关文章:
- 通过依赖类型使用非类型模板参数的单类型模板参数类模板的部分专用化
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- 为什么依赖模板类型在部分专用化中不可推导?
- 具有可变参数非类型参数的模板专用化
- 检查子类型时的专用方法模板
- 特定类型的模板函数的专用化
- 将"模板<类型名 T>zero()"扩展/专用为可调用的"T"
- 模板专用化和明确指定返回类型与自动
- 将返回类型专用化为 void 或 const 左值引用
- 专用于类型集的函数模板
- 有没有办法根据 lambda 参数返回类型部分专用化我的模板化函数?
- 为什么 std::optional::value_or 没有默认 ctor 类型的专用化?
- 具有模板专用化的泛型类型转换
- cpp 模板专用化,错误说参数 1 的类型为 T,这取决于参数 T
- 具有不同非类型模板参数的模板类部分专用化
- 从具有部分专用化的boost:hana::set中提取类型失败
- 带有void类型和参数的C++11模板专用化
- 常量和非常量类型的相同模板专用化
- 具有专用和非专用类型的模板重载
- 是否可以派生自和"respecialize"具有派生自专用类型的类型的专用类?