为什么C ++标准库中没有transform_if? [英] Why is there no transform_if in the C++ standard library?

查看:151
本文介绍了为什么C ++标准库中没有transform_if?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想要进行有条件的复制时出现了一个用例(1.可用于 copy_if ),但从值容器到指向这些值的指针的容器(2 。可以与 transform 一起使用)。

A use case emerged when wanting to do a contitional copy (1. doable with copy_if) but from a container of values to a container of pointers to those values (2. doable with transform).

使用可用的工具,我不能做到这一点只需不到两个步骤:

With the available tools I can't do it in less than two steps :

#include <vector>
#include <algorithm>

using namespace std;

struct ha { 
    int i;
    explicit ha(int a) : i(a) {}
};

int main() 
{
    vector<ha> v{ ha{1}, ha{7}, ha{1} }; // initial vector
    // GOAL : make a vector of pointers to elements with i < 2
    vector<ha*> ph; // target vector
    vector<ha*> pv; // temporary vector
    // 1. 
    transform(v.begin(), v.end(), back_inserter(pv), 
        [](ha &arg) { return &arg; }); 
    // 2. 
    copy_if(pv.begin(), pv.end(), back_inserter(ph),
        [](ha *parg) { return parg->i < 2;  }); // 2. 

    return 0;
}

当然,我们可以叫 remove_if pv 上的c>并不需要临时的,更好的是,实现(对于一元操作),如下所示:

Ofcourse we could call remove_if on pv and eliminate the need for a temporary, better yet though, it's not difficult to implement (for unary operations) something like this :

template <
    class InputIterator, class OutputIterator, 
    class UnaryOperator, class Pred
>
OutputIterator transform_if(InputIterator first1, InputIterator last1,
                            OutputIterator result, UnaryOperator op, Pred pred)
{
    while (first1 != last1) 
    {
        if (pred(*first1)) {
            *result = op(*first1);
            ++result;
        }
        ++first1;
    }
    return result;
}

// example call 
transform_if(v.begin(), v.end(), back_inserter(ph), 
[](ha &arg) { return &arg;      }, // 1. 
[](ha &arg) { return arg.i < 2; });// 2.




  1. 可用的C ++标准库工具是否有更优雅的解决方法?

  2. 库中是否不存在 transform_if 的原因?现有工具的组合是否是足够的解决方法和/或被认为具有良好的性能表现?

  1. Is there a more elegant workaround with the available C++ standard library tools ?
  2. Is there a reason why transform_if does not exist in the library? Is the combination of the existing tools a sufficient workaround and/or considered performance wise well behaved ?


推荐答案

标准库支持基本算法。

容器和算法应尽可能彼此独立。

Containers and algorithms should be independent of each other if possible.

同样地,作为速记的形式,很少包含可以由现有算法组成的算法。

Likewise, algorithms that can be composed of existing algorithms are only rarely included, as shorthand.

如果需要转换,可以平凡地编写它。如果您希望今天/今天/组成现成商品而不产生开销,则可以使用具有惰性范围的范围库,例如 Boost.Range ,例如:

If you require a transform if, you can trivially write it. If you want it /today/, composing of ready-mades and not incur overhead, you can use a range library that has lazy ranges, such as Boost.Range, e.g.:

v | filtered(arg1 % 2) | transformed(arg1 * arg1 / 7.0)

@hvd在评论中指出, transform_if double产生不同的类型(在这种情况下为 double )。合成顺序很重要,使用Boost Range,您还可以编写:

As @hvd points out in a comment, transform_if double result in a different type (double, in this case). Composition order matters, and with Boost Range you could also write:

 v | transformed(arg1 * arg1 / 7.0) | filtered(arg1 < 2.0)

导致不同的语义。这就说明了这一点:

resulting in different semantics. This drives home the point:


包含 > std :: filter_and_transform , std :: transform_and_filter std :: filter_transform_and_filter 等。等等。

it makes very little sense to include std::filter_and_transform, std::transform_and_filter, std::filter_transform_and_filter etc. etc. into the standard library.

请参阅示例 在Coliru上直播

See a sample Live On Coliru

#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>

using namespace boost::adaptors;

// only for succinct predicates without lambdas
#include <boost/phoenix.hpp>
using namespace boost::phoenix::arg_names;

// for demo
#include <iostream>

int main()
{
    std::vector<int> const v { 1,2,3,4,5 };

    boost::copy(
            v | filtered(arg1 % 2) | transformed(arg1 * arg1 / 7.0),
            std::ostream_iterator<double>(std::cout, "\n"));
}

这篇关于为什么C ++标准库中没有transform_if?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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