问题
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