2011-01-06 70 views
2

是否有任何常见的方法来摆脱自定义的“分配”仿函数?的std ::变换可能是巨大的,但根据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; 
} 
+0

好问题。修改每个元素将允许将文本字符串就地转换为全部小写或全部大写。 – 2011-01-06 00:10:41

回答

3

STD修改集合元素::变换的变形例()确实允许输出迭代器指向与输入范围的开始相同的元素。见here。代码示例显示了这一点,它演示了具有两个输入范围的转换。输出迭代器与第一个输入迭代器相同。这是否使它更可口?

+1

是的,这个工程。但是标准说(参见25.3.4变换):... op和binary_op不应该使迭代器或子范围无效,或者修改范围[first1,last1] ... – Voivoid 2011-01-06 00:17:27

+0

中的元素。这不会修改元素,它会替换他们。这不会使迭代器无效。 – OrangeDog 2011-01-06 00:21:08

+0

它修改了迭代器指向的地方,没有迭代器本身。新值仍将由同一个迭代器指向。 – 2011-01-06 00:25:02

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

谢谢。boost :: lambda看起来不错。 BOOST_FOREACH也很棒,但它不允许用这对迭代器指定所需的序列。我仍然想知道std :: transform是否可以用来修改输入序列。任何意见将不胜感激 – Voivoid 2011-01-06 00:42:13

1

什么@gregg说加:

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

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

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

这里是C++ 03的一行添加3〜每个值关arr

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

相关问题