【问题标题】:How much of STL is too much? [closed]多少 STL 太多了? [关闭]
【发布时间】:2009-04-09 13:26:38
【问题描述】:

我在std::for_eachbind 等中使用了很多STL 代码,但我注意到有时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 的类似反模式?

【问题讨论】:

  • 顺便说一句,如果在您的第​​二个示例中,“X”对于所有元素都是相同的。只需将它传递给 Foo 的构造函数并将其存储在仿函数中,而不是绑定它。简单得多。
  • 你实际上没有使用任何 STL,所以你很安全 :)
  • 只是一种意见,但“太多”是指您使用并非仅仅为了使用它们而需要的功能。如果它有帮助,请使用它。如果您担心名称过长,您始终可以使用 typedef 或命名空间别名来缩短它们(例如,typedef std::vector::iterator VecIter;)。标准库的问题是,它通常是在给定编译器上做某事的最干净的通用方法,仅仅是因为编译器的创建者或最了解它的人(如果不是创建者)将编写它的实现。不要害怕在有用的时候使用它。

标签: c++ stl coding-style


【解决方案1】:

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
}

【讨论】:

  • ...直到达到 10 个参数,也就是说! :)
  • 此时你将它们组合在一个结构中:)
  • 不,此时您重新考虑要求函数具有 10 个参数的架构;)
  • 这正是我所做的。 std::for_each 太丑了。 BOOST_FOREACH 好多了
【解决方案2】:

它也可以反过来。假设您从一个只需要几行代码的操作开始。你不想费心创建一个只会被调用一次的函数,只是为了压缩循环,所以你写这样的东西:

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

然后随着您需要执行的操作变得越来越复杂,您意识到将其拉入一个单独的函数是有意义的,因此您最终会得到

for ()
    do_alot_more_stuff();

然后将其修改为像您的原始方法一样,进一步压缩它是有意义的:

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

最后,真正将 for_each 更改为 for 循环有多难,反之亦然?不要因为小细节而自责!

【讨论】:

    【解决方案3】:

    像使用任何其他语言工具一样使用它。当它使您的生活更轻松时,请使用它。当它变得麻烦时,做其他事情。当需求发生变化时,以一种或另一种方式重构循环并不是真的很难。

    【讨论】:

    • 没错。更改代码有什么问题?
    【解决方案4】:

    与您的问题类似,我经常注意到 C++ 中的“函子”模式/习语实际上非常笨拙。这就是为什么我期待 C++0X 中的Lambda Functions。现在使用 boost::lambda 可以实现其中的一些。

    【讨论】:

    • 天啊,语法... 0X 还有 8 个月的时间,再加上 3 年以上的时间,直到主要编译器供应商赶上来。那会很长。
    • @Anton:它已经在 g++ 和 Visual Studio 10 中(RC 现已免费提供)
    【解决方案5】:

    我在算法中的很多东西都遇到了同样的问题。它有一种令人讨厌的趋势,即最终成为更多只使用老式 for 循环的代码。

    我真的无法证明使用适当的构造函数和析构函数,也许还有一些访问器来创建一些特殊的仿函数类(这是 C++ 中的一个中等高级主题,我的许多维护者不会完全理解)避免单行 for 循环。

    【讨论】:

      【解决方案6】:

      也许你一开始就使用了 for_each 而不是 transform...

      【讨论】:

        【解决方案7】:

        我从不使用 std::for_each (或很少使用)。

        我建议现在使用Boost.Foreach 和经典的“for”结构。当 C++0x 发布时,您可以考虑使用新的“for”构造,使其更易于遍历容器。

        【讨论】:

        • 迫不及待地等待 C++ 得到一个真正的“for”循环(而不是它现在拥有的美化的 while 循环)。
        【解决方案8】:

        还可以考虑 Parallelism,通过一个函数,您可以定义将发生什么变化,并指示一系列元素是否可以并行完成,而不是从开始到结束一次 1 个。

        【讨论】:

          【解决方案9】:

          或者您可以等待 C++0x 并使用 for(elem&amp; e, container){e.something();}
          BOOST_FOREACH() 完全一样,但属于标准的一部分(在某些年份...)。

          【讨论】:

            猜你喜欢
            • 2014-05-05
            • 1970-01-01
            • 1970-01-01
            • 2011-01-19
            • 2011-03-12
            • 1970-01-01
            • 1970-01-01
            • 2011-06-02
            • 1970-01-01
            相关资源
            最近更新 更多