Whoa, no it doesn't. C++ is far more verbose than necessary for things like creating algebraic datatypes or really creating any types.
Whoa, no it doesn't. C++ is far more verbose than necessary for things like creating algebraic datatypes or really creating any types.
std::vector<int>::iterator it;
for (it=arr.begin(); it!=arr.end(); it++) {
...
}
as an improvement over for (int i=0; i<len; i++) {
...
}
Not entirely unrelated: I'm currently busy verbosifying a large chunk of C++11 code into C++90 code because Reasons (or so the maintainers assure me). std::vector<int> myVec;
for( auto it = myVec.begin(); it != myVec.end(); ++it );
or if you prefer the external begin/end syntax: for( auto it = std::begin(myVec); it != std::end(myVec); ++it );
or the most succinct (replace && by & if writing): for( auto && item : myVec );That is strictly not necessary. `auto&&` is what is now being called a universal reference: `item` resolves to `const int&` if `myVec` is const, and to `int&` if `myVec` is mutable. `auto&&` does the right thing in the majority of cases. In fact, the following extension [1] has been proposed for C++17 (and already implemented in recent clang builds):
for( item : myVec ) { /* do stuff */ }
which is meant to be a short-hand for for( auto&& item : myVec ) { /* do stuff */ }
[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n399... for(auto& item : vec)
syntax was merely a talking point being tossed around C++0x meetings. And to this day the project I'm working on still hasn't officially dropped support for C++90 so I'm stuck with the old syntax anyway :/ template <class T>
void foo(T arr)
{
for (auto it = arr.begin(); it != arr.end(); ++it)
{
std::cout << *it << std::endl;
}
}
You could pass a `std::map<int>` to `foo`, or a `std::list<string>`, or a `std::vector<char>`. You could even create your own classes and give them to `foo`, as long as they implement the `begin`/`end` protocol.It's certainly more verbose than necessary, but it can be convenient.
Ideally, it should be something like:
for (auto it : arr) {
// do something with *it
}The advantage of iterators is that they're incredibly flexible. You can use them for sub-ranges, reversed ranges, non-ranges like input and output iterators, etc, etc. This is vastly more powerful than something like, say, Objective C's NSFastEnumeration, which just allows for the trivial case handled by the range-based for-loop.
Because there are algorithms where you may not want to walk through the whole collection. STL wasn't meant to be a container library alone, it also includes many generic algorithms that work using iterators to delimit the range of data to be operated upon.
Times have changed now of course.
Just to write a class in C++ with a constructor and destructor which are not inlined, you have to repeat the class name about seven times: three times in the class declaration. Then four more times in the definitions of those two functions:
class verbose {
public:
verbose();
~verbose();
};
verbose::verbose()
{
}
verbose::~verbose()
{
}