我想执行lambda列表中的第一个lambda,它不是用boost hana完成的。我已经用hana::if_成功地做到了这一点,但它不能扩展到任何数量的lambda。我想我想要对find_if进行懒惰的评估,但我似乎没有很好地掌握hana的documentation,无法找到正确的语法。这就是你可以告诉我我试图以错误的方式解决它的地方,或者帮助我找到一种允许我懒惰地进行计算的语法。
您可以在Godbolt上找到包含此问题的所有代码的现场示例。
示例:假设我想实现一个通用的addToContainer函数
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); }, [] {});
}这应该是如下行为,它确实是这样的:
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
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);
}但是,这将失败,因为
Value of: v
Expected: equals { 1, 2, 3 }
Actual: { 1, 2, 3, 3 }因为std::vector上同时存在insert和push_back。
所以,相反,我希望hana懒惰地评估sfinaes。
我已经尝试了以下方法,但我对documentation的理解还不够好,无法找到我想要实现的正确语法。
这无法编译:
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链接。
发布于 2021-08-20 04:11:15
我自己找到了一个solution,不是用hana::sfinae,而是用hana::is_valid
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); });
}https://stackoverflow.com/questions/68856709
复制相似问题