2009-04-09 105 views
6

我使用了很多STL代码std::for_eachbind,等等,但我注意到有时使用STL不是好主意。STL有多少太多?

例如,如果你有一个std::vector和想要做的向量的每个项目一个动作,你的第一个想法就是用这样的:

std::for_each(vec.begin(), vec.end(), Foo()) 

,它是优雅和OK,一会。但是接下来是第一组错误报告,您必须修改代码。现在,你应该添加参数来调用Foo(),所以现在就变成:

std::for_each(vec.begin(), vec.end(), std::bind2nd(Foo(), X)) 

但这只是治标不治本。现在项目已经成熟,并且您更好地理解业务逻辑,并且希望为代码添加新的修改。在这一点上,你意识到你应该使用旧的好东西:

for(std::vector::iterator it = vec.begin(); it != vec.end(); ++it) 

这是只发生在我身上吗?你在代码中认识到这种模式吗?您是否使用过STL体验过类似的反模式?

+1

顺便说一句,如果在你的第二个例子中,所有元素的“X”是相同的。只需将它传递给Foo的构造函数,并将其存储在函数中而不是绑定它。简单得多。 – 2009-04-09 14:04:46

+0

你实际上没有使用STL,所以你很安全:) – 2016-06-23 16:52:28

+0

只是一个意见,但“太多”是当你使用的功能,你不需要仅仅为了使用它们。如果有用,请使用它。如果你担心名字太长,你总是可以使用typedef或命名空间别名来缩短它们(例如`typedef std :: vector :: iterator VecIter;`)。使用标准库的事情是,它通常是在给定的编译器上执行某些操作的最简洁的通用方法,仅仅是因为编译器的创建者或最了解它的人(如果不是创建者)会编写它的实现。不要害怕在有用时使用它。 – 2016-06-23 18:09:39

回答

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

...直到你得到10个参数,那就是! :) – Kylotan 2009-04-09 13:37:27

+1

在这一点你把他们在一个结构:) – 2009-04-09 13:40:13

3

您的问题类似,我常常发现,在C++中的 “仿” 模式/成语其实是相当笨重。这就是为什么我期待在C++ 0X中使用Lambda Functions。现在有一些可以使用boost :: lambda。

10

虽然它也可以相反。假设你从一个只需要几行的操作开始。你不想打扰创造一个只会被调用一次,就凝聚了循环功能,让你写的东西,如:

for() 
{ 
    // do 
    // some 
    // stuff 
} 

然后,你需要执行变得更加复杂,你实现操作那拉成一个单独的函数是有道理的,所以你最终与

for() 
    do_alot_more_stuff(); 

然后修改它要像你原来的方法很有意义,进一步凝聚了下去:

std::for_each(begin, end, do_alot_more_stuff); 

最后,要真正将for_each更改为for循环有多困难,反之亦然?不要让自己超越细节!

5

像任何其他语言工具一样使用它。当它让你的生活更轻松时,就使用它。当它变得繁琐时,请做其他事情。当需求改变时,并不是以某种方式重构循环真的很难。

0

也想到并行化,用一个函数可以定义什么会改变,并指出一系列元素是否可以在平行而不是从开始到结束的一个时间内完成。

1

也许你用的for_each而不是摆在首位变换...

1

我从来没有使用std :: for_each的(或很少)。

我建议现在使用Boost.Foreach和经典的“for”构造。当C++ 0x出来时,你可以考虑使用新的“for”构造,使得迭代容器更具可读性。

0

或者你可以等待的C++ 0x和使用for(elem& e, container){e.something();}
不太一样BOOST_FOREACH(),但该标准的一部分(在某些年份...)。

2

我在算法中遇到了很多问题。它有一个令人讨厌的趋势,最终被更多代码,只是使用一个老式的循环。

我真的没有理由去用适当的构造函数和析构函数创建一些特殊的函子类(这是C++中的中等高级主题,许多维护者不会完全理解),也许有些访问器,只是为了避免单线循环。