【问题标题】:Fold expressions with arbitrary callable?折叠表达式与任意可调用?
【发布时间】:2015-02-19 09:10:04
【问题描述】:

查看折叠上的 C++17 paper(以及 cppreference),我很困惑为什么选择只与运算符一起使用?乍一看,通过在args 的元素之间插入一个+ 标记似乎可以更轻松地扩展(... + args),但我不相信这是一个很好的决定。

为什么二进制 lambda 表达式不能像上面的后者一样工作并遵循相同的扩展?在不支持任意可调用对象的情况下将折叠语法添加到语言中,这让我感到震惊,那么该语法是否允许以一种我看不到的方式使用它们?


更新:这适用于带有 clang 的可变参数 min() 函数

template <typename T>
struct MinWrapper {
    const T& obj;
};

template <typename T, typename U, typename V=std::common_type_t<T,U>>
constexpr MinWrapper<V> operator%(
        const MinWrapper<T>& lhs, const MinWrapper<U>& rhs) {
    return {lhs.obj < rhs.obj ? lhs.obj : rhs.obj};
}


template <typename... Ts>
constexpr auto min(Ts&&... args) {
    return (MinWrapper<Ts>{args} % ...).obj;
}

【问题讨论】:

  • 折叠表达式的主要原因是用于概念。 “普通”用户代码已经可以用普通库算法实现各种折叠。
  • @KerrekSB 仍然可以有一个使用概念的可调用对象,并且除了应用运算符之外还可以做一些事情
  • 好点。写一篇论文。
  • 呸。现在我需要想办法让它与命名运算符一起工作。唔。可能是不可能的。嗯。
  • 我认为只有运营商才能保持提案的规模较小。另请查看支持空包的有限操作列表 - 我想如果您允许任意 bin-fns,则必须扩展整个内容以干净地处理它。也就是说,与您的 Q 一致,我发现该提案相当简洁,更不用说半成品。

标签: c++ fold c++17


【解决方案1】:

那是一篇很棒的论文和一个出色的语言特性。如果我们绕过我不是特别喜欢的标准谈话,我想提出一个解决方法。由于我没有 c++17 编译器(或时间机器),我的答案只会是概述,我相信可能是,一种用语言提供 具有任意函数的折叠表达式 的解决方案现状。

1。定义一个类型包装器(一个轻量级的)

template<typename T>
struct wp {
    T const& val; 
    // yes there should be constructors
};

2。将包装转换为包裹包装的机械

template<typename Op, typename Ts...>
using wrapped_pack = make_wrapped<Op, Ts..>

3。重载wp&lt;T&gt; 的内置运算符

template<typename T, typename U>
ret_val operator+(wp<T> const& lhs, wp<U> const& rhs) {...}

4。在折叠表达式中使用包装的包

这需要一个额外的层,将折叠的args 转换为包装参数


上面的一个明显缺点是它不能保证唯一性(或可伸缩性):每个带有自定义可调用对象的折叠都会消耗内置的运算符重载。

应该有一些技巧可以根据遇到的表达式来改变类型,但我不想深入思考实验(例如,已经在包装器类型中使用 Op 的类型提供了更多的扩展空间)。

【讨论】:

  • clang 来自其 svn 仓库的当前负责人支持使用 -std=c++1z 进行折叠
【解决方案2】:

首先,我很高兴我所写的内容在 clang 中有效(我看到您的更新实现了我提到的 4 个步骤中的 3 个)。我必须感谢 Nick Athanasiou,因为我在写this 之前曾与我讨论过这个技术。

我现在提到这个的原因是因为我被告知他发布了一个实现这些东西的library(在boost库incubator中);您可以找到相关文档here。这似乎是最初的想法(我们都在这里使用)并允许这样的代码:

(Op<Max>(args) + ...); // Op is a function producing the custom fold type

由于惰性求值和有状态运算符而被排除在外(或尚未包括在内,不能确定)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-20
    • 1970-01-01
    相关资源
    最近更新 更多