【问题标题】:C++ BOOST ForEach vs custom defined MacroC++ BOOST ForEach 与自定义宏
【发布时间】:2013-04-17 06:35:51
【问题描述】:

使用 BOOST 的 ForEach 和我自己的自定义 #define 宏来迭代容器有什么区别??

我的:

#define iterate(i,x)     for(typeof(x.begin()) i=x.begin();i!=x.end();++i)

boost:
#include <string>
#include <iostream>
#include <boost/foreach.hpp>

int main()
{
    std::string hello( "Hello, world!" );

    BOOST_FOREACH( char ch, hello )
    {
        std::cout << ch;
    }

    return 0;
}

请解释哪种方法更好,为什么?

【问题讨论】:

  • Boost 可能已将其代码配置为在没有非标准 typeof 扩展名的编译器上运行。
  • 一个区别是BOOST_FOREACH 与普通数组一起工作,即char a[] = {"Hello, world!"};
  • 你不应该依赖typeof,那不是标准的 C++。你应该使用decltype
  • @MariusBancila 如果您有一个支持decltype 的编译器,那么它很可能也支持基于范围的for 循环,在这种情况下,这两个宏都是不必要的。编辑:但是,再想一想,我认为 VS2010 支持前者,但不支持后者:-S
  • @Praetorian,完全同意。

标签: c++ boost macros iterator boost-iterators


【解决方案1】:

第一个很大的区别是当你使用右值时,像这样:

vector<int> foo();

// foo() is evaluated once
BOOST_FOREACH(int i, foo())
{

}

// this is evaluated twice(once for foo().begin() and another foo().end())
iterate(i, foo())
{

}

这是因为BOOST_FOREACH 检测它是否为右值并进行复制(编译器可以省略)。

第二个区别是BOOST_FOREACH 使用Boost.Range 来检索迭代器。这使得它可以很容易地扩展。所以它适用于数组和std::pair

第三个区别是你的iterate 宏会自动推断范围的类型,这在支持typeof 但不支持auto 的旧编译器上非常方便。但是,BOOST_FOREACH 将适用于所有 C++03 编译器。

【讨论】:

  • 您似乎在暗示 BOOST_FOREACH 仅适用于支持 auto 的编译器。这不是真的。 BOOST_FOREACH 不使用任何 C++11 功能,实际上适用于非常古老的编译器。 BOOST_FOREACH 是 100% 兼容 C++03,这是它与 OP 的 iterate 宏之间的另一个区别。
  • @EricNiebler 对不起,我不是暗示它需要auto,我更正了它以使其更清楚。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多