c++ - 获取满足特征的 std::tuple 的第一个元素
问题描述
我正在使用 C++17。我想获得满足某种类型特征的元组元素。如果可以通用地提供特征,那将是惊人的,但我会对某个特征的特定功能感到满意。用法可能如下所示:
auto my_tuple = std::make_tuple { 0.f, 1 };
auto basic = get_if_integral (my_tuple);
auto fancy = get_if<std::is_floating_point> (my_tuple);
std::cout << basic; // '1'
std::cout << fancy; // '0.f'
理想情况下,如果多个元素满足该特征,则编译将失败,例如std::get (std::tuple)
.
解决方案
这是一种不使用递归的非常简单的方法:
template <template <typename...> typename T, typename... Ts>
constexpr int index_of_integral(const T<Ts...>&)
{
const bool a[] = { std::is_integral_v<Ts>... };
for (int i = 0; i < sizeof...(Ts); ++i) if (a[i]) return i;
return -1;
}
template <typename T>
constexpr decltype(auto) get_if_integral(T&& t)
{
return std::get<index_of_integral(t)>(std::forward<T>(t));
}
int main()
{
constexpr auto t = std::make_tuple(3.14, 42, "xyzzy");
static_assert(get_if_integral(t) == 42);
}
它可以很容易地扩展到对特征进行参数化。
使它成为 C++17 的唯一因素是is_integral_v
变量 template 和 single-argument static_assert
。其他一切都是 C++14。
请注意,在 C++20 中,for
循环可以替换为std::find
and std::distance
。
理想情况下,它应该抛出异常而不是返回-1,但编译器似乎不喜欢这样。
受到这个答案的启发。
推荐阅读
- json - 在 Swift 中使用 Structs 的 JSON 解码器没有成员错误问题
- azure - 不支持构造函数“DisableAttribute(Type)”。为服务总线队列触发的 Azure 函数生成函数元数据时出错
- python - 输入请求时输入错误 Django Rest Framework
- java - 如何将新的 Java Oracle 许可证添加到我的应用程序?
- count - 日期范围之间的 Power BI 累积计数
- sql - 如何使用分组集根据列值计算总计?
- javascript - 在 Vue mount() 中使用 THREE.js 加载 STL 文件
- r - 向量中仅某些元素的 N 次排列
- python - 如何从 Git 子模块中正确导入 PyInstaller 构建的应用程序?
- java - 映射和管理实体的问题,Hibernate