我在STL
,std::for_each
等处使用了很多bind
代码,但我注意到有时使用STL
并不是个好主意。
例如,如果您有一个std::vector
,并希望对向量的每个项目执行一个操作,那么您的第一个想法就是使用它:
std::for_each(vec.begin(), vec.end(), Foo())
它很优雅,好一阵子。但随后出现了第一组错误报告,您必须修改代码。现在你应该添加参数来调用Foo()
,现在它变为:
std::for_each(vec.begin(), vec.end(), std::bind2nd(Foo(), X))
但这只是暂时的解决方案。现在项目已经成熟,您可以更好地理解业务逻辑,并且希望对代码添加新的修改。在这一点上你意识到你应该使用旧的好处:
for(std::vector::iterator it = vec.begin(); it != vec.end(); ++it)
这只发生在我身上吗?你在代码中认识到这种模式吗?您是否使用STL
体验了类似的反模式?
答案 0 :(得分:10)
使用boost::bind和std :: for_each以干净的方式解决了这个问题。或者您可以使用BOOST_FOREACH。
std :: for_each:
的示例std::for_each(v.begin(), v.end(), boost::bind(&C::f, _1, param));
BOOST_FOREACH示例:
std::list<int> list_int( /*...*/ );
BOOST_FOREACH( int i, list_int )
{
// do something with i
}
答案 1 :(得分:10)
它也可以采用相反的方式。假设您从一个只需要几行的操作开始。你不想打扰创建一个只调用一次的函数,只是为了压缩循环,所以你写了类似的东西:
for ()
{
// do
// some
// stuff
}
然后,当您需要执行的操作变得更复杂时,您会意识到将其拉入单独的函数是有意义的,因此您最终会使用
for ()
do_alot_more_stuff();
然后修改它就像你的原始方法一样有意义进一步压缩它:
std::for_each(begin, end, do_alot_more_stuff);
最后,真正将for_each更改为for循环有多难,反之亦然?不要因为微小的细节而殴打自己!
答案 2 :(得分:5)
像任何其他语言工具一样使用它。当它让您的生活更轻松时,请使用它。当它变得麻烦时,做其他事情。当需求发生变化时,并不是很难以某种方式重构循环。
答案 3 :(得分:3)
与您的问题类似,我经常注意到C ++中的“仿函数”模式/习语实际上非常笨拙。这就是为什么我期待C ++ 0X中的Lambda Functions。现在可以使用boost :: lambda来实现其中的一些功能。
答案 4 :(得分:2)
我在算法中遇到了很多问题。它有一种令人讨厌的倾向,最终只是使用一个老式的for循环更多代码。
我无法通过适当的构造函数和析构函数以及可能的一些访问器创建一些特殊的functor类(这是C ++中的一个中等高级主题,我的许多维护者都无法完全理解)避免单行for循环。
答案 5 :(得分:1)
也许你首先使用for_each而不是变换......
答案 6 :(得分:1)
我从不使用std :: for_each(或很少)。
我建议现在使用Boost.Foreach和经典“for”构造。当C ++ 0x出来时,您可以考虑使用新的“for”构造,使迭代容器更具可读性。
答案 7 :(得分:0)
还要考虑并行性,通过一个函数,您可以定义将要更改的内容,并指示是否可以在并行中完成一系列元素,而不是从开始到结束一次完成。
答案 8 :(得分:0)
或者您可以等待C ++ 0x并使用for(elem& e, container){e.something();}
与BOOST_FOREACH()
完全相同,但是标准的一部分(在某些年份......)。