From the c++0x Wikipedia site:
int my_array[5] = {1, 2, 3, 4, 5};
for (int &x : my_array) {
x *= 2;
}
So why does this code not work?
int main(int argc, char* argv[])
{
for (char *arg : argv)
{
// Do something.
}
}
Error:
main.cpp:36: error: no matching function for call to ‘begin(char**&)’
I am using Qt with g++ 4.6.1 on Ubuntu 11.10.
Additional Information
Is There a Range Class in C++0x
Range-Based For-Loop Statement Definition Redundance
Range-based for loop in C++ is added since C++ 11. It executes a for loop over a range. Used as a more readable equivalent to the traditional for loop operating over a range of values, such as all elements in a container.
Colon ':' is basically a operator which indicates that the y is inside x and assign the y's value to the elements of array one by one.
argv(ARGument Vector) is array of character pointers listing all the arguments. If argc is greater than zero,the array elements from argv[0] to argv[argc-1] will contain pointers to strings. Argv[0] is the name of the program , After that till argv[argc-1] every element is command -line arguments.
Range-for is as fast as possible since it caches the end iterator[citationprovided], uses pre-increment and only dereferences the iterator once. Then, yes, range-for may be slightly faster, since it's also easier to write there's no reason not to use it (when appropriate).
Usually, the first thing I do with argc
and argv
is this:
std::vector<std::string> arguments(argv, argv + argc);
Now I have a vector of strings to work with and I can easily use not only the range-based for loops, but also C++ standard library facilities.
for(std::string& s : arguments) {
// do stuff...
}
The wikipedia code works because the type of my_array
is a variable of array type.
The original code does not work, because argv
is not an array. The syntax char* argv[]
may make it look like it is an array, but that's just a sad artifact of C syntax. char* argv[]
is exactly the same as char** argv
. argv
is not an array; it's actually just a pointer.
The range-based for loop works on:
begin()
and end()
that return iterators;begin
and end
that can be called like begin(x)
and end(x)
, with x
being the thing that you're iterating over.As you can see, pointers are not part of this list.
You don't, because the system can't tell how long argv
is at compile time. Someone can likely find the proper section of the standard to quote you about this.
There is a way around it though, and that's to create a custom class to wrap argv
. It's not even that hard.
class argv_range {
public:
argv_range(int argc, const char * const argv[])
: argc_(argc), argv_(argv)
{
}
const char * const *begin() const { return argv_; }
const char * const *end() const { return argv_ + argc_; }
private:
const int argc_;
const char * const *argv_;
};
Here's how you use it:
for (const char *arg: argv_range(argc, argv)) {
// Do something.
}
Yeah, I use a lot of const
s. Basically, argv
is an array of character pointers, none of which should be modified, each pointing to a string, none of the characters of which should be modified either.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With