What's the C++98 equivalent of the auto iterator reference?

六月ゝ 毕业季﹏ 提交于 2019-12-24 14:00:19

问题


My development environment has RHEL 5.8 which does not support GCC 4.8+ modern (C++11+) compilers. I anticipate that someday we'll get there, so I have a header file where I define macros based on C++11 support levels so I can do something like this:

#if defined(CPP11_auto_type_inference) && defined(CPP11_range_based_for_loops)
  for (auto vit : args)
#else
  std::vector<std::string>::const_iterator vit, vend;
  for (vend=args.end(),vit=args.begin(); vit != vend; ++vit)
#endif
  { // process arguments...
    std::cout << "Processing \"" << *vit << '"' << std::endl;
    . . .
  } // end "process arguments" loop

So, what I'm trying to do in C++98 is the equivalent of the iterator reference (or is it more accurate to say "a dereferenced iterator"?), like below:

for (auto& it : args)
  std::cout << "Processing \"" << it << '"' << std::endl;

For the life of me, I cannot figure out how to get a dereferenced iterator (or iterator reference) in C++98. I can simulate, as below:

#if defined(CPP11_auto_type_inference) && defined(CPP11_range_based_for_loops)
  for (auto& it : args) {
#else
  std::vector<std::string>::const_iterator vit, vend;
  for (vend=args.end(),vit=args.begin(); vit != vend; ++vit) {
    std::string it(*vit);
#endif
    std::cout << "Processing \"" << it << '"' << std::endl;
    . . .
  }

... but I'm really hoping that is not the answer.

What is the C++98 equivalent of for (auto& it : vec), or is it not possible? Is it only possible to "simulate" it but dereferencing the iterator and creating a copy each iteration?

And if that be the case, is that what is going on "under the covers" with C++11 auto& syntax? (I have to believe this is not the case.) In any case, is it more costly to use for (auto& it : vec) than for (auto it : vec)?

Thank you in advance for your insight.


回答1:


I think you are going into too much trouble to emulate C++11 functionality. You can use C++98/03 method for now. They will continue to work when you are able to use a C++11 compiler.

Having said that, you can use:

#if defined(CPP11_auto_type_inference) && defined(CPP11_range_based_for_loops)
  for (auto vit : args)
#else
  std::vector<std::string>::const_iterator viter, vend;
  for (vend=args.end(),viter=args.begin(); viter != vend; ++viter)
  {
     std::string vit = *viter;
#endif
     { // process arguments...
       std::cout << "Processing \"" << vit << '"' << std::endl;
       . . .
     } // end "process arguments" loop
#if defined(CPP11_auto_type_inference) && defined(CPP11_range_based_for_loops)  
#else
  }
#endif

If you want to emulate the equivalent of

  for (auto& vit : args)

you can use:

     std::string const& vit = *viter;



回答2:


This has been done before in C++ 98, my favorite solution is Niebler's in Conditional Love: FOREACH Redux

To get a taste of the "hackery" involved in doing this take a look at how an "auto_iterator" is defined

struct auto_any_base {};

template< class T > struct auto_any :
auto_any_base
{
   auto_any( T const & t ) : item( t ) {}
   mutable T item;
};

template< class Container >
auto_any< typename Container::const_iterator >
begin( Container const & c )
{
   return c.begin();
}

As the name "auto_any" suggests, this is a general mechanism for putting an object of unknown type in automatic storage (i.e. it is not dynamically allocated using new).

Now, to (begin creating) a FOREACH macro we can say:

#define BOOST_FOREACH( item, container ) \
   auto_any_base const & iter = begin( container ); \ 

There's working code in the link (and a lot, lot, looooot more to digest when reading this)



来源:https://stackoverflow.com/questions/32898302/whats-the-c98-equivalent-of-the-auto-iterator-reference

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!