我正在使用 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::find
和 std::distance
。
理想情况下它应该抛出异常而不是返回 -1,但编译器似乎不喜欢这样。
灵感来自this answer .
关于c++ - 获取 std::tuple 满足特征的第一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53250540/