c++ - 如果我们不想将每个元素转换为一个转换元素,而是两个,我们如何使用 std::transform?

标签 c++ c++11 stl iterator

如果我们不想将每个元素转换为一个转换元素,而是两个,我们如何使用std::transform

下面的伪代码说明了我想要实现的目标

std::transform(a.cbegin(), a.cend(), std::back_inserter(b), [](T const& x) {
    return f(x) and g(x);
});

当然,我可以调用 std::transform 两次,但这会很烦人。也许我们需要提供一个自定义的插入器。还有其他选择吗?

最佳答案

transform 仅用于进行一对一的转换。自定义插入器无论如何也帮不了你,因为 transform 是这样实现的:

while (first1 != last1) {
    *d_first++ = unary_op(*first1++); // you have no way to write
                                      // more than one element
}
return d_first;

您实际上必须为 a 编写一个自定义迭代器来迭代每个元素两次,然后在您的仿函数中保持状态以了解您是否在 f 状态或 g 状态。你可以看到这变得多么复杂。

除了简单的 1-1 转换之外,您应该只使用 for 循环:

for (const auto& x : a) {
    b.push_back(f(x));
    b.push_back(g(x));
}

即使对于简单的 1-1 转换,我认为简单的 range-for 表达式也能胜任。

您还可以编写自己的转换,它接受任意数量的仿函数:

template <typename InIt, typename OutIt, typename... Functors>
void transform(InIt first, InIt last, OutIt d_first, Functors... fs)
{
    while (first != last) {
        apply(*first, d_first, fs...);
        first++;
    }
}

与;

template <typename In, typename OutIt>
void apply(const In&, OutIt ) { }

template <typename In, typename OutIt, typename F, typename... Functors>
void apply(const In& in, OutIt& out, F f, Functors... fs)
{
    *out++ = f(in);
    apply(in, out, fs...);
}

用作(example):

transform(a.begin(), a.end(), back_inserter(b), f, g);

关于c++ - 如果我们不想将每个元素转换为一个转换元素,而是两个,我们如何使用 std::transform?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29866376/

相关文章:

c++ - 在调用函数时使用相同的对象实例作为参数和调用对象

C++ 可变参数函数 : use number of parameters as template argument

c++ - 父级上 protected 构造函数和继承的默认构造函数不 protected

c++ - 二进制 '=' : no operator found which takes a right-hand operand of type 'std::unique_ptr<char [],std::default_delete<_Ty>>'

c++ - 没有已知的参数 1 从 'Traffic_light' 到 'Traffic_light&' 的转换

c++ - Primer 显示错误,但代码在 GCC 上运行良好

c++ - 在一个线程中创建对象并使用 std::atomic 访问另一个线程

c++ - 为什么 priority_queue 没有 front() 而有 top()

c++ - 如何处理多个迭代器类型

c++ - 对多维数组使用拷贝