【问题标题】:How can I find if an element exists in a tuple?如何查找元组中是否存在元素?
【发布时间】:2016-10-25 06:44:23
【问题描述】:

假设我有一个std::tuple:

std::tuple<Types...> myTuple;
// fill myTuple with stuff

现在我想知道 func 是否为 lambda 中的任何元素返回 true,其中 func 是某个 lambda,例如:

auto func = [](auto&& x) -> bool { return someOperation(x); }

我该怎么做?请注意,Types... 可能很大,所以我不想每次都遍历 all 元素。

【问题讨论】:

  • 好像是this的副本。
  • @m8mble 我添加了一行来强调为什么这是不同的(基本上这是 for_eachany_of 之间的区别 - 当你找到它时停止在元素上)。
  • 那些看起来不像可行的欺骗目标。你想要什么作为返回类型? variant? size_t索引?
  • std::apply([](auto&amp;&amp;... args) { return (someOperation(decltype(args)(args)) || ...); }, myTuple);

标签: c++ tuples c++14


【解决方案1】:
#include <tuple>

std::tuple<int, char, double> myTuple{ 1, 'a', 3.14f };

bool result = std::apply([](auto&&... args) {
                           return (someOperation(decltype(args)(args)) || ...);
                         }
                       , myTuple);

DEMO

【讨论】:

  • 在这种情况下它可以只是args,但一般来说,如果有人会在apply 中输入std::move(myTuple),那么我相信转发可能会有用
  • 我会提到 std::apply 是 C++17。
  • @skypjack 折叠表达式也是如此
【解决方案2】:

这是一个 C++14 解决方案:

template <typename Tuple, typename Pred>
constexpr bool any_of_impl(Tuple const&, Pred&&, std::index_sequence<>) {
    return false;
}

template <typename Tuple, typename Pred, size_t first, size_t... is>
constexpr bool any_of_impl(Tuple const& t, Pred&& pred, std::index_sequence<first, is...>) {
    return pred(std::get<first>(t)) || any_of_impl(t, std::forward<Pred>(pred), std::index_sequence<is...>{});
}

template <typename... Elements, typename Pred, size_t... is>
constexpr bool any_of(std::tuple<Elements...> const& t, Pred&& pred) {
    return any_of_impl(t, std::forward<Pred>(pred), std::index_sequence_for<Elements...>{});
}

live demo

【讨论】:

  • 很好的解决方案,但我不确定在为元组元素的每个索引实例化 any_of_impl 时使用 std::integer_sequence 是否会增加编译时间,不是吗?
  • @W.F.我正要回复说我需要这个,因为元组可能有重复的类型并且get&lt;type&gt; 不起作用,但是通过这种递归短路我不需要这个。我会更新一个更好的版本,谢谢。
【解决方案3】:

这里有一点复古的 c++11 解决方案:

#include <iostream>
#include <tuple>

template <class Tuple, class Lambda>
bool any_of(Tuple &&tup, Lambda lambda, std::integral_constant<size_t, std::tuple_size<Tuple>::value> i) {
    return false;
}

template <class Tuple, class Lambda, class I = std::integral_constant<size_t, 0>>
bool any_of(Tuple &&tup, Lambda lambda, I i = {}) {
    return lambda(std::forward<typename std::tuple_element<i, Tuple>::type>(std::get<i>(tup))) ||
           any_of(std::forward<Tuple>(tup), lambda, std::integral_constant<size_t, i+1>{});
}

int main() {
   std::cout << any_of(std::forward_as_tuple(1, 2, 3, 4), [](int&& i) { return i == 2; }) << std::endl;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多