c++ - 获取 std::tuple 满足特征的第一个元素

标签 c++ c++17 variadic-templates template-meta-programming stdtuple

我正在使用 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 变量模板和单参数 static_assert。其他一切都是 C++14。

请注意,在 C++20 中,for 循环可以替换为 std::findstd::distance

理想情况下它应该抛出异常而不是返回 -1,但编译器似乎不喜欢这样。

灵感来自this answer .

关于c++ - 获取 std::tuple 满足特征的第一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53250540/

相关文章:

c++ - 包装一个通用函数以从字符串中获取它的参数

c++ - 绑定(bind)可变参数函数 C++

c++ - 为 tic-tac-toe 实现 minimax 算法

c++ - std::map 线程安全

c++ - 为什么 INVOKE 总是取消引用数据成员而不是尽可能调用?

c++ - 为什么原始字符串文字的分隔符必须小于 16 个字符?

c++ - 为什么删除列表的_first_ 元素会使 `.rend()` 无效?

c++ - 快速 n 为大 n 选择 k mod p?

c++17倍表达式语法

c++ - 用户定义的文字如何与数字分隔符一起使用?