修改集合的每个元素

时间:2011-01-06 00:03:30

标签: c++ boost stl

有没有什么常见的方法可以摆脱自定义'assign'仿函数? std :: transform可能很棒,但根据c ++标准,它禁止修改源元素

目标是使用尽可能多的声明方法修改集合元素

template <typename T>
struct assign : std::binary_function<T, T, void> {
    void operator()( const T& source, T& dest ) {
        dest = source;
    }
};

int main() {
    static boost::array<int, 5> arr = { 1, 2, 3, 4, 5 };
    std::for_each( arr.begin(), arr.end(), 
        boost::bind( assign<int>(), boost::bind( std::plus<int>(), _1, 3 ), _1 ) );
    return 0;
}

3 个答案:

答案 0 :(得分:3)

std :: transform()允许输出迭代器指向与输入范围开头相同的元素。见here。代码示例基本上显示了演示具有两个输入范围的变换的行。输出迭代器与第一个输入迭代器相同。这会让它变得更可口吗?

答案 1 :(得分:2)

尝试Boost.Lambda:

int main() {
    using namespace boost::lambda;
    static boost::array<int, 5> arr = { 1, 2, 3, 4, 5 };
    std::for_each( arr.begin(), arr.end(), _1 += 3 );
    return 0;
}

然而,只是一个“for_each”循环:

int main() {
    static boost::array<int, 5> arr = { 1, 2, 3, 4, 5 };
    BOOST_FOREACH(int& n, arr) {
        n += 3;
    }
    return 0;
}

答案 2 :(得分:1)

@gregg所说的加号:

标准中的措辞(N1905 25.2.3第2段)禁止转换函数直接修改给定范围内的元素,即它不能写入输入迭代器。它只应该计算一个值,transform函数然后分配给result迭代器。事实上,第5段明确允许result等于first

我想这可能允许实现在特定情况下执行安全检查或优化。

例如,假设transform专门用于std::vector<char>。在32位机器上,实现可以将主循环展开4次并执行32位加载和存储而不是8位加载。显然,如果对转换函数的第一次调用修改了输入范围(在存储然后对脏数据进行操作之前剩余的3次调用),这将无法工作。

这是C ++ 03 one-liner,为每个值arr添加3:

std::transform(arr.begin(), arr.end(), arr.begin(), std::bind1st(std::plus<int>(), 3));