折叠具有任意可调用的表达式? [英] Fold expressions with arbitrary callable?

查看:116
本文介绍了折叠具有任意可调用的表达式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

查看C ++ 17 论文(和 cppreference ),我很困惑为什么选择只与运营商合作?乍一看,它似乎可以更容易扩展(... + args)只需推一个 + args 的元素之间的标记,但我不相信这是一个伟大的决定。让我们以总和为例:

Looking over the C++17 paper on folds, (and on cppreference), I'm confused as to why the choice was made to only work with operators? At first glance it seems like it would make it easier to expand (... + args) by just shoving a + token between the elements of args, but I'm unconvinced this is a great decision. Let's take the sum example of:

template <typename... Ts>
auto sum(Ts&&... args) {
    return (args + ... + 0);
}

sum(6,10, 5); c> body可以扩展到 return(6 +(10 +(5 + 0))),但可以等价扩展为 return operator +(6,operator +(10,operator +(5,0))); (如果我错了,我真的不明白为什么只有一个运算符是一个好的决定。

and a call with sum(6, 10, 5); The body could expand to return (6 + (10 + (5 + 0))) but could equivalently expand to return operator+(6, operator+(10, operator+(5, 0))); (correct me if I'm wrong about that one). I don't really see why having just an operator is a good decision.

为什么二进制lambda表达式不能正常工作并遵循与上述相同的扩展?对我来说,折叠语法将被添加到一个语言,而不支持任意可调用,所以语法允许使用一种方式,我只是没有看到吗?

Why can't a binary lambda expression work just as well and follow the same expansion as the latter above? It's jarring to me that a fold syntax would be added to a language without support for arbitrary callables, so does the syntax allow a way to use them that I'm just not seeing?

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

Update: This works for a variadic min() function with clang

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;
}


推荐答案

光荣语言功能。如果我们绕过标准化的谈话,我不太喜欢,我想提出一个解决方法。因为我没有一个c ++ 17编译器(或时间机器)我的答案将只是大纲,我相信是一个解决方案提供折叠表达式任意函数与语言状态。

That's a great paper and a glorious language feature. If we bypass the standardese talk, which I'm not particularly fond of, I'd like to propose a workaround. Since I don't have a c++17 compiler (or a time machine) my answer will only be outlining, what I believe could be, a solution to providing fold expressions with arbitrary functions with the language status as is.

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



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



2. Machinery to transform packs to wrapped packs

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



3。为 wp< T>

重载内置运算符

3. Overload a built in operator for wp<T>

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



4。在fold表达式中使用包装包



这需要一个额外的图层,其中 args 到包装的参数

上述的一个明显缺点是它不能保证唯一性(或可扩展性)与自定义函子将消耗内置运算符重载。

An obvious shortcoming of the above is that it doesn't guarantee uniqueness (or scalability) : every fold with a custom functor would consume a built in operator overloading.

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

There should be hacks to vary the types based on the expression they're encountered in but I don't want to dive that deep into a thought experiment (eg using the type of Op in the type of the wrapper already gives much more space to scale into).

这篇关于折叠具有任意可调用的表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆