在类型的元组上使用 hana 过滤器:"use of boost::hana::not_equal_t before deduction of auto"

Using hana filter on tuple of types: "use of boost::hana::not_equal_t before deduction of auto"

我正在尝试过滤 hana::tuple_t,根据我的理解,这只是 hana::tuplehana::type 个对象。

我查看了 the example in the documentation 中的一些代码,即:

template <typename Any>
auto switch_(Any& a) {
  return [&a](auto ...cases_) {
    auto cases = hana::make_tuple(cases_...);
    auto default_ = hana::find_if(cases, [](auto const& c) {
      return hana::first(c) == hana::type_c<default_t>;
    });
    static_assert(default_ != hana::nothing,
      "switch is missing a default_ case");
    auto rest = hana::filter(cases, [](auto const& c) {
      return hana::first(c) != hana::type_c<default_t>;
    });
    // ...
  };
}

在这种情况下(同样,如果我的理解是正确的),caseshana::tuplehana::pair 对象,其中 first 元素对是一个 hana::type 对象。

这是我的代码,它应该以相同的方式工作:

#include <boost/hana/tuple.hpp>
#include <boost/hana/filter.hpp>
namespace hana = boost::hana;

int main() {
    auto types_tuple = hana::tuple_t<int, float, char>;
    auto filtered_tuple = hana::filter(types_tuple, [](auto const & type) {
        return type != hana::type_c<float>;
    });
}

这里的目标是 filtered_tuple 最终与 hana::tuple_t<int, char> 相同。

这不编译。我得到了很长的编译器输出,但相关部分(我认为)是:

/usr/include/boost/hana/detail/operators/comparable.hpp: In instantiation of ‘constexpr auto boost::hana::detail::operators::operator!=(X&&, Y&&) [with X = boost::hana::type_impl<int>::_&; Y = const boost::hana::type_impl<float>::_&; <template-parameter-1-3> = void]’:
/path/to/test.cpp:9:21:   required from ‘main()::<lambda(auto:1)> [with auto:1 = boost::hana::type_impl<int>::_]’
/usr/include/boost/hana/filter.hpp:105:34:   required by substitution of ‘template<class ... X> boost::hana::detail::filter_indices<static_cast<bool>(boost::hana::detail::decay<decltype((((const boost::hana::detail::make_filter_indices<main::__lambda0>*)this)->boost::hana::detail::make_filter_indices<main::__lambda0>::pred)(static_cast<X&>(boost::hana::detail::make_filter_indices::operator()::x))), typename std::remove_reference<decltype((((const boost::hana::detail::make_filter_indices<main::__lambda0>*)this)->boost::hana::detail::make_filter_indices<main::__lambda0>::pred)(static_cast<X&>(boost::hana::detail::make_filter_indices::operator()::x)))>::type>::type::value) ...> boost::hana::detail::make_filter_indices<main()::<lambda(auto:1)> >::operator()<X ...>(X&& ...) const [with X = {boost::hana::type_impl<int>::_&, boost::hana::type_impl<float>::_&, boost::hana::type_impl<std::__cxx11::basic_string<char> >::_&}]’
/usr/include/boost/hana/basic_tuple.hpp:117:39:   required from ‘static constexpr decltype(auto) boost::hana::unpack_impl<boost::hana::basic_tuple_tag>::apply(boost::hana::detail::basic_tuple_impl<std::integer_sequence<long unsigned int, _Idx ...>, Xn ...>&, F&&) [with long unsigned int ...i = {0, 1, 2}; Xn = {boost::hana::type_impl<int>::_, boost::hana::type_impl<float>::_, boost::hana::type_impl<std::__cxx11::basic_string<char> >::_}; F = boost::hana::detail::make_filter_indices<main()::<lambda(auto:1)> >]’
/usr/include/boost/hana/unpack.hpp:47:29:   required from ‘constexpr decltype(auto) boost::hana::unpack_t::operator()(Xs&&, F&&) const [with Xs = boost::hana::basic_tuple<boost::hana::type_impl<int>::_, boost::hana::type_impl<float>::_, boost::hana::type_impl<std::__cxx11::basic_string<char> >::_>&; F = boost::hana::detail::make_filter_indices<main()::<lambda(auto:1)> >]’
/usr/include/boost/hana/tuple.hpp:225:32:   required from ‘static constexpr decltype(auto) boost::hana::unpack_impl<boost::hana::tuple_tag>::apply(Xs&&, F&&) [with Xs = boost::hana::tuple<boost::hana::type_impl<int>::_, boost::hana::type_impl<float>::_, boost::hana::type_impl<std::__cxx11::basic_string<char> >::_>&; F = boost::hana::detail::make_filter_indices<main()::<lambda(auto:1)> >]’
/usr/include/boost/hana/unpack.hpp:47:29:   required from ‘constexpr decltype(auto) boost::hana::unpack_t::operator()(Xs&&, F&&) const [with Xs = boost::hana::tuple<boost::hana::type_impl<int>::_, boost::hana::type_impl<float>::_, boost::hana::type_impl<std::__cxx11::basic_string<char> >::_>&; F = boost::hana::detail::make_filter_indices<main()::<lambda(auto:1)> >]’
/usr/include/boost/hana/filter.hpp:123:29:   required from ‘static constexpr auto boost::hana::filter_impl<S, boost::hana::when<boost::hana::Sequence<S>::value> >::apply(Xs&&, const Pred&) [with Xs = boost::hana::tuple<boost::hana::type_impl<int>::_, boost::hana::type_impl<float>::_, boost::hana::type_impl<std::__cxx11::basic_string<char> >::_>&; Pred = main()::<lambda(auto:1)>; S = boost::hana::tuple_tag]’
/usr/include/boost/hana/filter.hpp:48:29:   required from ‘constexpr auto boost::hana::filter_t::operator()(Xs&&, Pred&&) const [with Xs = boost::hana::tuple<boost::hana::type_impl<int>::_, boost::hana::type_impl<float>::_, boost::hana::type_impl<std::__cxx11::basic_string<char> >::_>&; Pred = main()::<lambda(auto:1)>]’
/path/to/test.cpp:10:6:   required from here
/usr/include/boost/hana/detail/operators/comparable.hpp:40:33: error: use of ‘constexpr auto boost::hana::not_equal_t::operator()(X&&, Y&&) const [with X = boost::hana::type_impl<int>::_&; Y = const boost::hana::type_impl<float>::_&]’ before deduction of ‘auto’
         { return hana::not_equal(static_cast<X&&>(x), static_cast<Y&&>(y)); }
                  ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我正在使用 Boost 1.65.1 和 C++17。

为什么我的代码不起作用?据我所知,“在推导 auto 之前使用某些返回 auto 的函数”通常来自递归,例如 , which makes sense. But there's no recursion here. There is also 这似乎与我的问题密切相关,但事实并非如此完全一样,答案对我没有帮助。

您只缺少一个 #include<boost/hana/not_equal.hpp>

Online Demo