C++ 可任意调用的折叠表达式?

C++ 可任意调用的折叠表达式?,c++,fold,c++17,C++,Fold,C++17,回顾C++17中的折叠(以及其他),我不明白为什么选择只与操作符一起工作?乍一看,只需在args的元素之间推一个+标记,就可以更容易地扩展(…+args),但我不相信这是一个伟大的决定 为什么二进制lambda表达式不能同样工作,并遵循与上面后者相同的扩展?在不支持任意可调用项的情况下,折叠语法会被添加到语言中,这让我感到不安,那么语法是否允许使用我没有看到的方法呢 更新:这适用于带有叮当声的变量min()函数 template <typename T> struct MinWra

回顾C++17中的折叠(以及其他),我不明白为什么选择只与操作符一起工作?乍一看,只需在
args
的元素之间推一个
+
标记,就可以更容易地扩展
(…+args)
,但我不相信这是一个伟大的决定

为什么二进制lambda表达式不能同样工作,并遵循与上面后者相同的扩展?在不支持任意可调用项的情况下,折叠语法会被添加到语言中,这让我感到不安,那么语法是否允许使用我没有看到的方法呢


更新:这适用于带有叮当声的变量
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;
}
模板
结构MinWrapper{
const T&obj;
};
模板
constexpr MinWrapper运算符%(
常量最小包装器和左侧、常量最小包装器和右侧){
返回{lhs.obj
这是一篇很棒的论文,也是一个很棒的语言功能。如果我们绕过我并不特别喜欢的standardese谈话,我想提出一个解决办法。由于我没有c++17编译器(或时间机器),我的答案将只是概述一个解决方案,我相信这可能是一个解决方案,用任意函数提供折叠表达式,语言状态保持不变

1.定义类型包装(轻量级包装)
模板
结构可湿性粉剂{
T常数&val;
//是的,应该有建设者
};
2.将包装转换为包裹包装的机械
模板
使用包裹的包装=使包裹
3.为
wp
模板
ret_val运算符+(wp const&lhs,wp const&rhs){…}
4.在折叠表达式中使用包裹的包装 这需要一个额外的层,其中折叠的
args
被转换为包装参数


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


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

首先,我很高兴我所写的东西能够很好地工作(我看到您的更新实现了我提到的4个步骤中的3个)。我必须赞扬
在写作前与我讨论过的这一技巧

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

(Op<Max>(args) + ...); // Op is a function producing the custom fold type
(Op(args)+…);//Op是一个生成自定义折叠类型的函数

被忽略了,取而代之的是懒惰的求值和有状态的操作符(或者还没有包括在内,不能确定)

折叠表达式的主要原因是用于概念。“普通”用户代码已经可以通过普通的库算法实现各种折叠。@KerrekSB One仍然可以有一个可调用的,它使用概念并执行一些操作,而不是应用运算符。写一篇论文。现在我需要找到一种方法,让它与命名操作符一起工作。嗯,可能不可能。meh。我认为只有运营商才能将提案保持在较小的范围内。再看看支持空包的有限的OP列表——我想如果你允许任意的bin FN,那么整个事情都必须扩展以干净地处理它。也就是说,与您的问题相一致,我觉得该提案相当简洁,更不用说半生不熟了。
clang
其svn回购的当前头部支持使用
-std=c++1z的折叠
template<typename Op, typename Ts...>
using wrapped_pack = make_wrapped<Op, Ts..>
template<typename T, typename U>
ret_val operator+(wp<T> const& lhs, wp<U> const& rhs) {...}
(Op<Max>(args) + ...); // Op is a function producing the custom fold type