首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >助推hana first sfinae成功

助推hana first sfinae成功
EN

Stack Overflow用户
提问于 2021-08-20 03:32:13
回答 1查看 77关注 0票数 0

我想执行lambda列表中的第一个lambda,它不是用boost hana完成的。我已经用hana::if_成功地做到了这一点,但它不能扩展到任何数量的lambda。我想我想要对find_if进行懒惰的评估,但我似乎没有很好地掌握hanadocumentation,无法找到正确的语法。这就是你可以告诉我我试图以错误的方式解决它的地方,或者帮助我找到一种允许我懒惰地进行计算的语法。

您可以在Godbolt上找到包含此问题的所有代码的现场示例。

示例:假设我想实现一个通用的addToContainer函数

代码语言:javascript
复制
template <class T>
void addToContainerIf(T &container, const typename T::value_type &element) {
  auto optional_inserted =
      hana::sfinae([&element](auto &c) { return c.insert(end(c), element); });
  auto optional_push_backed = hana::sfinae([&element](auto &c) {
    c.push_back(element);
    return end(c)--;
  });
  hana::if_(
      hana::is_nothing(optional_inserted(container)),
      [&] { optional_push_backed(container); }, [] {});
}

这应该是如下行为,它确实是这样的:

代码语言:javascript
复制
void testIf() {
  std::vector<int> v{1, 2};
  std::vector<int> expected{1, 2, 3};
  addToContainerIf(v, 3);
  if (v.size() != expected.size()) {
    std::cout << "If implementation failed: Expected v to have "
              << expected.size() << " elements, but it has " << v.size()
              << std::endl;
  } else {
    std::cout << "If implementation succeeded." << std::endl;
}

现在我想要更改addToContainerIf,使其使用hana::tuple来查找第一个lambda,即hana::just

代码语言:javascript
复制
template <class T>
void addToContainerTuple(T &container, const typename T::value_type &element) {
  auto optional_inserted =
      hana::sfinae([&element](auto &c) { return c.insert(end(c), element); });
  auto optional_push_backed = hana::sfinae([&element](auto &c) {
    c.push_back(element);
    return end(c)--;
  });
  hana::find_if(
      hana::transform(hana::make_tuple(optional_inserted, optional_push_backed),
                      [&](auto f) { return f(container); }),
      hana::is_just);
}

但是,这将失败,因为

代码语言:javascript
复制
Value of: v
Expected: equals { 1, 2, 3 }
  Actual: { 1, 2, 3, 3 }

因为std::vector上同时存在insertpush_back

所以,相反,我希望hana懒惰地评估sfinaes。

我已经尝试了以下方法,但我对documentation的理解还不够好,无法找到我想要实现的正确语法。

这无法编译:

代码语言:javascript
复制
template <class T>
void addToContainerTupleLazy(T &container, const typename T::value_type &element) {
  auto optional_inserted =
      hana::sfinae([&element](auto &c) { return c.insert(end(c), element); });
  auto optional_push_backed = hana::sfinae([&element](auto &c) {
    c.push_back(element);
    return end(c)--;
  });
  hana::eval(
      hana::find_if(
          hana::transform(hana::make_tuple(optional_inserted, optional_push_backed),
                          [&](auto f) { return hana::make_lazy(f)(container); }),
          hana::make_lazy(hana::is_just)
      )
  );
}

请参阅编译错误的godbolt链接。

EN

回答 1

Stack Overflow用户

发布于 2021-08-20 04:11:15

我自己找到了一个solution,不是用hana::sfinae,而是用hana::is_valid

代码语言:javascript
复制
template <class T>
void addToContainerTupleLazy(T &container,
                             const typename T::value_type &element) {
  auto optional_inserted = [&element](auto &c) {
    return c.insert(end(c), element);
  };
  auto optional_push_backed = [&element](auto &c) {
    c.push_back(element);
    return end(c)--;
  };

  hana::transform(
      hana::find_if(hana::make_tuple(optional_inserted, optional_push_backed),
                    [&](auto f) { return hana::is_valid(f)(container); }),
      [&](auto f) { return f(container); });
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68856709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档