使用 for_each 和 bind 反转向量中的字符串
我想知道如何在一个“简单”行中使用单个 for_each
命令来反转 vector
中包含的 string
。
是的,我知道使用自定义函子很容易,但我不能接受,它不能使用 bind
来完成(至少我不能这样做)。
#include <vector>
#include <string>
#include <algorithm>
std::vector<std::string> v;
v.push_back("abc");
v.push_back("12345");
std::for_each(v.begin(), v.end(), /*call std::reverse for each element*/);
编辑: 非常感谢这些有趣的解决方案。 但是,我的解决方案是不使用 tr1::bind 随 Visual Studio 2008 功能包/SP1 一起提供。我不知道为什么它不能按预期工作,但事实就是如此(甚至 MS 也承认它有问题)。也许一些修补程序会有所帮助。
使用 boost::bind 一切都会按预期工作并且非常简单(但有时非常混乱:))。我真的应该首先尝试 boost::bind ......
I was wandering how it's possible to reverese string
s that are contained in a vector
using a single for_each
command just in one "simple" line.
Yea, I know it is easy with a custom functor, but I can't accept, that it can't be done using bind
(at least I couldn't do it).
#include <vector>
#include <string>
#include <algorithm>
std::vector<std::string> v;
v.push_back("abc");
v.push_back("12345");
std::for_each(v.begin(), v.end(), /*call std::reverse for each element*/);
Edit:
Thanks a lot for those funtastic solutions.
However, the solution for me was not to use the tr1::bind that comes with the Visual Studio 2008 feature pack/SP1. I don't know why it does not work like expected but that's the way it is (even MS admits that it's buggy). Maybe some hotfixes will help.
With boost::bind everything works like desired and is so easy (but sometimes relly messy:)). I really should have tried boost::bind in the first place...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
std::for_each 需要一个一元函数(或者至少具有一元函数的 typedef)。
std::reverse<>是二元函数。它需要两个迭代器。可以使用 boost::bind 将它们绑定在一起,但这将是一个非常可怕的混乱。像这样的东西:
我认为更好的是编写一个名为reverse_range的可重用函数,如下所示:(
可能使用一些元编程来确保 Range& 不是双重引用)
然后在 for_each 中使用它(在将其调整为当然是一元函数)。
编辑:
因为 string::begin 和 string::end 都有 const 和非常量变体,所以有必要对它们进行强制转换(正如 litb 在我写它们来测试我的答案时发现的那样......+1!)。这使得它非常冗长。 Typedef 可以让它变得更卫生一点,但要坚持一句简单的主题:
这只是为了重构而尖叫。
最后,因为我很无聊,C++0x 的奖励积分:
编辑:boost::bind 工作得很好,不需要 boost::lambda。
std::for_each expects a unary function (or at least something with the typedefs of a unary function).
std::reverse<> is a binary function. It takes two iterators. It would be possible to bind it all together using boost::bind, but it would be a pretty horrible mess. Something like:
Better, I think, would be to write a reusable function called reverse_range like so:
(probably with some metaprogramming to ensure that Range& isn't a double-reference)
And then use that in your for_each (after adapting it to be a unary function, of course).
EDIT:
Because string::begin and string::end have both const and non-const variants, it is necessary to cast them (as litb discovered while I was off writing them to test my answer ... +1!). This makes it very verbose. Typedefs can make it a bit more sanitary, but to stick with the one-liner theme:
Which just screams for refactoring.
Finally, because I'm bored, bonus points for C++0x:
EDIT: boost::bind works just fine, no need for boost::lambda.
你必须滚动你自己的反向对象:
现在你可以用一行来做:
You would have to roll your own reverse object:
Now you can do it one line:
使用 Boost.Phoenix2 :
套用 mr-edd 的话:可衡量的很棒 :)
完整示例:
打印:
With Boost.Phoenix2:
To paraphrase mr-edd: measurably awesomer :)
Full example:
prints:
也可以使用 BOOST_FOREACH 宏来完成:
it could be also done with the BOOST_FOREACH macro: