boost::hana: 为啥我不能过滤一个集合?
Posted
技术标签:
【中文标题】boost::hana: 为啥我不能过滤一个集合?【英文标题】:boost::hana: Why can't I filter a set?boost::hana: 为什么我不能过滤一个集合? 【发布时间】:2018-09-30 12:15:17 【问题描述】:我正在使用 boost::hana,我想过滤一个 boost::hana::set。
#include <boost/hana.hpp>
#include <type_traits>
int main()
using namespace boost::hana;
auto a = make_set(1,'a',3);
auto b = remove_if(a, [](const auto& x)return bool_c<std::is_same_v<decltype(x), char>>;);
// expects b to be make_set(1, 3);
这会导致 static_assert 失败。它告诉我:
static assertion failed: hana::remove_if(xs, predicate) requires 'xs' to be a MonadPlus
static_assert(hana::MonadPlus<M>::value,
为什么会失败?为什么集合不能是 MonadPlus,即使定义了空集合和连接操作?
【问题讨论】:
可能是因为集合不是序列,因为set
s 必须包含唯一元素。如果你想要更具体的东西,那么你可以在hana
的代码中找到hana::MonadPlus
的定义,然后再返回看看hana::set
缺少哪些先决条件。
这是一个完全合法且可以回答的问题。为什么它被否决了?
【参考方案1】:
如果你想过滤一个列表,你应该使用hana::tuple
。 Set 的概念比 MonadPlus 甚至 Monad 更普遍。您断言hana::set
具有hana::concat
或hana::empty
的实现是不正确的,此外它还要求数据结构是Monad。
根据您的示例,您正在寻找的可能是hana::difference
,但hana::set
本身对此毫无用处。它的操作需要hana::Comparable
并且不能很好地适应运行时状态。
如果您想按类型“过滤”集合并维护运行时值,我建议使用同样支持集合操作的hana::map
。您可以将其键设为其值的hana::type
。这仍然需要其类型的唯一性。
这是一个例子:
#include <boost/hana.hpp>
namespace hana = boost::hana;
constexpr auto typed_set = [](auto&& ...x)
return hana::make_map(
hana::make_pair(hana::typeid_(x), std::forward<decltype(x)>(x))...
);
;
int main()
auto a = typed_set(1, 'a', 3.0f);
auto b = typed_set('c');
auto c = hana::difference(a, b);
BOOST_HANA_RUNTIME_ASSERT(c == typed_set(1, 3.0f));
【讨论】:
以上是关于boost::hana: 为啥我不能过滤一个集合?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 boost::hana::tuple 转换为 std::variant