gpt4 book ai didi

c++ - 类型安全 - std::tuple 的 all_of/any_of/none_of

转载 作者:行者123 更新时间:2023-11-30 05:12:56 25 4
gpt4 key购买 nike

所以我开始实现一些算法来模仿 STL 算法的行为,但使用异构容器 a.k.a std::tuple。

template<typename UnaryPredicate, typename Tuple>
bool all_of(UnaryPredicate&& p, Tuple&& t) noexcept
{
return std::apply([&p](auto&& ...xs){ return (p(std::forward<decltype(xs)>(xs)) && ...); }, std::forward<Tuple>(t));
}

template<typename UnaryPredicate, typename Tuple>
bool any_of(UnaryPredicate&& p, Tuple&& t) noexcept
{
return std::apply([&p](auto&& ...xs){ return (p(std::forward<decltype(xs)>(xs)) || ...); }, std::forward<Tuple>(t));
}

template<typename UnaryPredicate, typename Tuple>
bool none_of(UnaryPredicate&& p, Tuple&& t) noexcept
{
return std::apply([&p](auto&& ...xs){ return !(p(std::forward<decltype(xs)>(xs)) || ...); }, std::forward<Tuple>(t));
}

如果您使用返回 bool 值的 UnaryPredicate,所有这些都可以正常工作。但如果没有呢?如何确保 UnaryPredicate 在调用元组的每个元素时返回 bool 值?另外,我如何检查 UnaryPredicate 是否真的没有抛出任何异常。

我知道有类型特征,如“is_nothrow_invocable”和“invoke_result”,但所有这些都需要元组包含的元素的类型。我真的必须使用“algorithm_impl”模式吗?

namespace impl
{
template<typename UnaryPredicate, typename Tuple, auto ...Is>
bool all_of_impl(UnaryPredicate&& p, Tuple&& t, std::index_sequence<Is...>) noexcept
{
return std::apply([&p](auto&& ...xs){ return (p(std::forward<decltype(xs)>(xs)) && ...); }, std::forward<Tuple>(t));
}
}

template<typename UnaryPredicate, typename Tuple>
bool all_of(UnaryPredicate&& p, Tuple&& t) noexcept
{
return impl::all_of_impl(std::forward<UnaryPredicate>(p), std::forward<Tuple>(t), std::make_index_sequence<std::tuple_size_v<std::decay_t<Tuple>>>{});
}

现在我可以做这样的事情:

std::enable_if_t<std::conjunction_v<std::is_same<std::invoke_result_t<std::decay_t<UnaryPredicate>, std::tuple_element_t<Is, std::decay_t<Tuple>>>, bool>...>, bool>

但这真的是要走的路吗?

编辑:

好吧,我一如既往地把事情复杂化了。我想我找到了一个可接受的解决方案:

template<typename UnaryPredicate, typename Tuple>
struct helper;

template<typename UnaryPredicate, typename Tuple>
struct helper2;

template<typename UnaryPredicate, typename ...Ts>
struct helper<UnaryPredicate, std::tuple<Ts...>>
: std::bool_constant<std::conjunction_v<std::is_same<bool, std::invoke_result_t<std::decay_t<UnaryPredicate>, std::decay_t<Ts>>>...>>
{};

template<typename UnaryPredicate, typename ...Ts>
struct helper2<UnaryPredicate, std::tuple<Ts...>>
: std::bool_constant<std::conjunction_v<std::is_nothrow_invocable<std::decay_t<UnaryPredicate>, std::decay_t<Ts>>...>>
{};

template<typename UnaryPredicate, typename Tuple>
inline constexpr auto helper_v{ helper<UnaryPredicate, Tuple>::value };

template<typename UnaryPredicate, typename Tuple>
inline constexpr auto helper2_v{ helper2<UnaryPredicate, Tuple>::value };


template<typename UnaryPredicate, typename Tuple>
std::enable_if_t<helper_v<UnaryPredicate, Tuple>, bool> all_of(UnaryPredicate&& p, Tuple&& t) noexcept(helper2_v<UnaryPredicate, Tuple>)
{
return std::apply([&p](auto&& ...xs){ return (p(std::forward<decltype(xs)>(xs)) && ...); }, std::forward<Tuple>(t));
}

template<typename UnaryPredicate, typename Tuple>
std::enable_if_t<helper_v<UnaryPredicate, Tuple>, bool> any_of(UnaryPredicate&& p, Tuple&& t) noexcept(helper2_v<UnaryPredicate, Tuple>)
{
return std::apply([&p](auto&& ...xs){ return (p(std::forward<decltype(xs)>(xs)) || ...); }, std::forward<Tuple>(t));
}

template<typename UnaryPredicate, typename Tuple>
std::enable_if_t<helper_v<UnaryPredicate, Tuple>, bool> none_of(UnaryPredicate&& p, Tuple&& t) noexcept(helper2_v<UnaryPredicate, Tuple>)
{
return std::apply([&p](auto&& ...xs){ return !(p(std::forward<decltype(xs)>(xs)) || ...); }, std::forward<Tuple>(t));
}

最佳答案

#define RETURNS(...) \
noexcept(noexcept(__VA_ARGS__)) \
-> decltype(__VA_ARGS__) \
{ return __VA_ARGS__; }

template<class UnaryPredicate, class Tuple>
auto all_of(UnaryPredicate&& p, Tuple&& t)
RETURNS(
std::apply(
[&p](auto&& ...xs){
return (p(std::forward<decltype(xs)>(xs)) && ...);
},
std::forward<Tuple>(t)
)
)

等等

关于c++ - 类型安全 - std::tuple 的 all_of/any_of/none_of,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44246600/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com