为什么BOOST_FOREACH不完全等同于手写代码? [英] Why is BOOST_FOREACH not exactly equivalent to handcoded one?

查看:217
本文介绍了为什么BOOST_FOREACH不完全等同于手写代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

boost doc


这导致接近最佳的代码生成;
BOOST_FOREACH的性能通常在等价的
手动循环的百分之几内。

This results in near-optimal code generation; the performance of BOOST_FOREACH is usually within a few percent of the equivalent hand-coded loop.

I猜测使用宏和非标准typeof运算符,我们可以生成完全等效的。 BOOST_FOREACH的什么功能使它不完全?

I guess using macros and non standard typeof operator, we can generate exactly equivalent one. What feature of BOOST_FOREACH makes it not exact?

编辑:

我的版本:

    #define EACH(it,v) \
      for(typeof(v.begin()) it = v.begin();it != v.end(); ++it)

//use this if you want a const_iterator from a non-const container

    #define CONST_EACH(it,v) \
      typedef typeof(v) v_type; \
      typedef const v_type& const_type; \
      for(typeof(static_cast<const_type>(v).begin()) it = static_cast<const_type>(v).begin(); it != static_cast<const_type>(v).end(); ++it)

我试图写一个没有任何开销的版本。这使用非标准typeof和给迭代器而不是value_type。我在这里缺少什么?

I am trying to write a version without any overhead. This uses non-standard typeof and gives iterator instead of value_type. Am I missing anything here?

推荐答案

Boost foreach不是微不足道。与gcc 4.6:

Boost foreach is far from trivial. with gcc 4.6:

int main()
{
    std::string hello( "Hello, world!" );
    BOOST_FOREACH( char ch, hello )
    {
        std::cout << ch;
    }
    return 0;
}

会生成很多使用 A?B :C

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

    if (
boost::foreach_detail_::auto_any_t _foreach_col9 = 
boost::foreach_detail_::contain( (hello) , (true ? 0 : 
boost::foreach_detail_::or_( 
boost::foreach_detail_::and_( 
boost::foreach_detail_::not_(
boost::foreach_detail_::is_array_(hello)) , (true ? 0 : 
boost::foreach_detail_::is_rvalue_( (true ? 
boost::foreach_detail_::make_probe(hello) : (hello)), 0))) , 
boost::foreach_detail_::and_( 
boost::foreach_detail_::not_(boost_foreach_is_noncopyable( 
boost::foreach_detail_::to_ptr(hello) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( 
boost::foreach_detail_::to_ptr(hello) , boost_foreach_argument_dependent_lookup_hack_value)))))) {} else if (
boost::foreach_detail_::auto_any_t _foreach_cur9 = 
boost::foreach_detail_::begin( _foreach_col9 , (true ? 0 : 
boost::foreach_detail_::encode_type(hello, 
boost::foreach_detail_::is_const_(hello))) , (true ? 0 : 
boost::foreach_detail_::or_( 
boost::foreach_detail_::and_( 
boost::foreach_detail_::not_(
boost::foreach_detail_::is_array_(hello)) , (true ? 0 : 
boost::foreach_detail_::is_rvalue_( (true ? 
boost::foreach_detail_::make_probe(hello) : (hello)), 0))) , 
boost::foreach_detail_::and_( 
boost::foreach_detail_::not_(boost_foreach_is_noncopyable( 
boost::foreach_detail_::to_ptr(hello) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( 
boost::foreach_detail_::to_ptr(hello) , boost_foreach_argument_dependent_lookup_hack_value)))))) {} else if (
boost::foreach_detail_::auto_any_t _foreach_end9 = 
boost::foreach_detail_::end( _foreach_col9 , (true ? 0 : 
boost::foreach_detail_::encode_type(hello, 
boost::foreach_detail_::is_const_(hello))) , (true ? 0 : 
boost::foreach_detail_::or_( 
boost::foreach_detail_::and_( 
boost::foreach_detail_::not_(
boost::foreach_detail_::is_array_(hello)) , (true ? 0 : 
boost::foreach_detail_::is_rvalue_( (true ? 
boost::foreach_detail_::make_probe(hello) : (hello)), 0))) , 
boost::foreach_detail_::and_( 
boost::foreach_detail_::not_(boost_foreach_is_noncopyable( 
boost::foreach_detail_::to_ptr(hello) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( 
boost::foreach_detail_::to_ptr(hello) , boost_foreach_argument_dependent_lookup_hack_value)))))) {} else for (bool _foreach_continue9 = true; _foreach_continue9 && !
boost::foreach_detail_::done( _foreach_cur9 , _foreach_end9 , (true ? 0 : 
boost::foreach_detail_::encode_type(hello, 
boost::foreach_detail_::is_const_(hello)))); _foreach_continue9 ? 
boost::foreach_detail_::next( _foreach_cur9 , (true ? 0 : 
boost::foreach_detail_::encode_type(hello, 
boost::foreach_detail_::is_const_(hello)))) : (void)0) if (
boost::foreach_detail_::set_false(_foreach_continue9)) {} else for (char ch = 
boost::foreach_detail_::deref( _foreach_cur9 , (true ? 0 : 
boost::foreach_detail_::encode_type(hello, 
boost::foreach_detail_::is_const_(hello)))); !_foreach_continue9; _foreach_continue9 = true)
    {
        std::cout << ch;
    }

    return 0;
}

有很多可能的类型,你可能想循环。对于c ++ 11,所有这些技巧不再需要,因为你可以循环几乎任何东西与

There are so many possibly types of things you may want to loop over. With c++11 all these tricks are not required anymore, as you can loop over almost anything with

for(auto const &a: something){  .. }

for(auto a=begin(something);a!=end(something);++i){  .. }

这篇关于为什么BOOST_FOREACH不完全等同于手写代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆