c++ - 具有动态选择的 C++ 模板类型
问题描述
我正在寻找一种允许编译器为模板参数中的给定整数选择最小数据类型的构造。我自己找不到解决方案的问题是我想如何使用它:
template<typename T, min_type<max_elements_to_store> max_elements_to_store>
class testClass {
private:
T data[max_elements_to_store];
min_type<max_elements_to_store> currently_selected_element;
};
宏“min_type”应该为给定的 max_elements_to_store (uint8_t, uint16_t, uint32_t, uint64_t) 动态选择具有最小位数的类型。我可以通过简单地将 min_type<> 替换为给定的数据类型来修复它,但这种数据类型通常不是最好的选择。例如,
template<typename T, uint64_t max_elements_to_store>
class testClass {
private:
T data[max_elements_to_store];
uint64_t currently_selected_element;
};
TestClass<uint8_t, 12> testObject;
在这里,数组只能保存 12 个元素,而 current_selected_element 变量浪费了很多位,而这些位对于仅访问 12 个元素来说是不必要的。这似乎只是一个小问题,但对于访问类中数据的许多变量来说,情况会变得更糟......
这个问题有解决方案吗?我希望很清楚我在寻找什么。
提前致谢!启发
解决方案
一种方法是使用std::conditional
:
#include <type_traits>
#include <cstdint>
#include <limits>
template<std::size_t Count>
using min_type = std::conditional_t<Count <= std::numeric_limits<uint8_t>::max(), uint8_t,
std::conditional_t<Count <= std::numeric_limits<uint16_t>::max(), uint16_t,
std::conditional_t<Count <= std::numeric_limits<uint32_t>::max(), uint32_t,
std::conditional_t<Count <= std::numeric_limits<uint64_t>::max(), uint64_t, void>>>>;
// test: all of the following pass
static_assert(std::is_same_v<min_type<12>, uint8_t>);
static_assert(std::is_same_v<min_type<1024>, uint16_t>);
static_assert(std::is_same_v<min_type<70000>, uint32_t>);
static_assert(std::is_same_v<min_type<5000000000>, uint64_t>);
template<typename T, std::size_t max_elements_to_store>
class testClass {
private:
T data[max_elements_to_store];
min_type<max_elements_to_store> currently_selected_element;
};
TestClass<uint8_t, 12> testObject;
注意:正如@François Andrieux 在评论中指出的那样,由于填充,这不会节省任何内存(除非您使用编译器特定的扩展来强制类的打包表示)。
推荐阅读
- python-3.x - 如何通过 Python 使用 ChromeDriver 和 Selenium 在 Chrome 中打开和访问多个(近 50 个)标签
- reactjs - clearInteval 不能与 ReactJS 一起工作
- java - HTTPUrlConnection 为 Linux 返回 400 但在 Windows 上工作
- android - 在 AsyncTask 上尝试使用 SQLite 检索数据的奇怪行为
- javascript - 最初加载 webpack 时查询的数据消失,然后当我转到网站上的其他页面并返回时出现
- label - Jena:推理规则的标签定义错误
- laravel - 试图获取非对象的属性“image_url”(查看:/app/resources/views/library.blade.php)
- mongodb - 使用 mongoose 在 mongodb 集合中添加带有字符串的电子邮件地址
- r - 重新排列 R 中热图的数据框
- youtube - 为什么我的 YouTube 订阅按钮变暗且无法点击?