检查所有std :: tuple元素是否满足条件+设计问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了检查所有std :: tuple元素是否满足条件+设计问题相关的知识,希望对你有一定的参考价值。

所以我试图验证std::tuple的所有元素是否符合某种条件。我目前的解决方案使用C ++ 17倍epxressions:

template <typename F, typename Tuple, size_t...Is>
_CR_INLINE bool tuple_all_of(F&& fn, Tuple&& t, std::index_sequence<Is...>) {
    return (std::forward<F>(fn)(std::get<Is>(std::forward<Tuple>(t))) && ...);
}

template <typename F, typename Tuple>
_CR_INLINE bool tuple_all_of(F&& fn, Tuple&& t) {
    return tuple_all_of(std::forward<F>(fn), std::forward<Tuple>(t), 
        std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>());
}

它在最新的clang和gcc中编译,但在MSVC中失败,因为折叠表达式尚未实现。 (https://blogs.msdn.microsoft.com/vcblog/2017/05/10/c17-features-in-vs-2017-3/

那么有没有使用折叠表达式的类似解决方案?


这是它应该如何使用:

template<typename...Components, typename Callable>
    void FindComponents(Callable&& fn) {
        for (auto& node : m_Entities) {
            auto tp = std::make_tuple(node.GetComponent<Components>()...);
            if (!tuple_all_of([](auto& p) { return p != nullptr; }, tp))
                continue;

            apply_from_tuple(fn, tp);
        }
    }

所以,只有当一个节点附加了所请求的组件时,我才会调用fn(即GetComponent!= nullptr)。也许有更好的解决方案?

答案

根据Visual C++ Language Conformance折叠表达式从VS2017 15.5开始支持/std:c++17(或/std:c++latest)编译器选项。

另一答案

您可以使用std::apply更轻松地解压缩元组:

template <typename F, typename Tuple>
constexpr bool tuple_all_of(F&& fn, const Tuple& t)
{
    return std::apply([&fn](const auto&... xs)
    {
        return (fn(xs) && ...);
    }, t);
}

折叠表达式可以用for_each_argument替换:

template <typename F, typename Tuple>
constexpr bool tuple_all_of(F&& fn, const Tuple& t)
{
    bool result = true;
    std::apply([&](const auto&... xs)
    {
        for_each_argument([&](const auto& x)
        {
            if(fn(x)) result = false;
        }, xs...);
    }, t);
    return result;
}

template <class F, class... Ts>
void for_each_argument(F f, Ts&&... a)
{
    (void)std::initializer_list<int>{(f(std::forward<Ts>(a)), 0)...};
}
另一答案

我想你可以使用未使用的C风格数组初始化的旧技巧[警告:代码未经过测试]

template <typename F, typename Tuple, size_t...Is>
_CR_INLINE bool tuple_all_of(F&& fn, Tuple&& t, std::index_sequence<Is...>) {
  using unused=bool[];

  bool ret { true };

  (void)unused { true, (ret = ret && std::forward<F>(fn)(std::get<Is>(std::forward<Tuple>(t)))) ... };

  return ret;
}

以上是关于检查所有std :: tuple元素是否满足条件+设计问题的主要内容,如果未能解决你的问题,请参考以下文章

std::tuple sizeof,是错过了优化吗?

python 检查每个元素是否满足条件

python 检查是否至少有一个元素满足条件

编写检查所有pandas DataFrame列值是否满足某个值?

JavaScript常用数组元素搜索或过滤的四种方法

JavaScript常用数组元素搜索或过滤的四种方法