user1500832
user1500832

Reputation: 85

C++ for each With a Pointer

I am trying to use a pointer to an array inside of a for each loop in C++. The code below won't work because the "for each statement cannot operate on variables of type 'int *'". I'd prefer to use the new operator so that the array is on the heap and not the stack, but I just can't seem to figure out the syntax here. Any suggestions?

#include <iostream>
using namespace std;

int main() {
    int total = 0;

    int* array = new int[6];
    array[0] = 10; array[1] = 20; array[2] = 30;
    array[3] = 40; array[4] = 50; array[5] = 60;

    for each(int i in array) {
        total += i;
    }

    cout << total << endl;
}

Upvotes: 2

Views: 14861

Answers (6)

Nathan822
Nathan822

Reputation: 198

VC++ is not different from ISO/ANSI C++. Anybody who tells you that it is, is wrong. Now, to answer your question of the for each statement. There is no such statement in the ISO C++ specification. Microsoft supports the 'foreach' statement in C#, as part of the .Net framework. As a result, there might be a chance that this is supported in Visual Studio, although I would recommend not using it.

Like the user shubhansh answered a few replies back, try using a vector. However, I'm guessing you would like to use a generic size, rather than hard-coding it in. The following for loop would help you in this regard:

    for(vector<int>::size_type i =0; i<myarray.size();i++)
{
total+=1;
}

This is the perfect way to iterate through a vector, as defined by the ISO standard. Hope this helps you in your development. Cheers!

Upvotes: 0

steffen
steffen

Reputation: 8988

You have to use an standard library collection such as std::vector or std::arrayto use for each.

Please note that this codee I not standard C++, therefore not portable, because for each is a Visual C++ extension. I recommend to use std::for_each or C++11 auto ranged loops.

Upvotes: 1

Benjamin Lindley
Benjamin Lindley

Reputation: 103751

That for each thing you are using is a Visual C++ extension that's not even recommended by some microsoft employees (I know I've heard STL say bad things about it, I can't remember where).

There are other options, like std::for_each, and range-based for from C++11 (though I don't think Visual C++ supports that yet). However, that's not what you should be using here. You should be using std::accumulate, because this is the job that it was made for:

total = std::accumulate(array, array + 6, 0);

If you're really just interested in how to use this Microsoft for each construct, well, I'm pretty sure you can't if you just have a pointer. You should use a std::vector instead. You should be doing that anyway.

Upvotes: 2

jmishra
jmishra

Reputation: 2081

The only way I can think about is iterating over array of reference types especially if you want your storage on the heap

Here Microsoft shows you how to do so

But for your case, the simplest alternative (if you want your array on the heap) would be as follows:-

 array<int>^ arr = gcnew array<int>{10, 20, 30, 40. 50, 60};
 int total = 0;    

for each (int i in arr){
  total+=i;
}

gcnew creates an instance of a managed type (reference or value type) on the garbage collected heap. The result of the evaluation of a gcnew expression is a handle (^) to the type being created.

Upvotes: 1

jsist
jsist

Reputation: 5253

you can always use for loop like this:

for (int i = 0; i < 6;i++)
{
total += array[i];
}

Although, answer for using "for each" using "gcnew" is already being given so I am omitting that. As an alternative, you can also use vectors as follows:

#include <iostream>
#include <vector>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    int total = 0;
    vector<int> myarray;

    myarray.push_back(10);
    myarray.push_back(20);
    myarray.push_back(30);
    myarray.push_back(40);
    myarray.push_back(50);
    myarray.push_back(60);

    for each(int i in myarray) {
        total += i;
    }

    cout << total << endl;
    return 0;
}

Hope this will help...

Upvotes: 2

SingerOfTheFall
SingerOfTheFall

Reputation: 29986

C++0x introduced a ranged-based for loops, which work equal to foreach in other languages. The syntax for them is something like this:

int arr[5]={1,2,3,4,5};
for( int & tmp : arr )
{
//do something
}

These loops work for C-style arrays, initializer lists, and any type that has begin() and end() functions defined for it that return iterators. I strongly believe that int * doesn't have begin() and end() functions for them that return iterators, because it's just a raw pointer. I also believe that other foreach-equivalents such as foreach in Qt, or what you've posted, work the same way, so you can't use them like this. msdn says that it works for collections:

for each (type identifier in expression) {
      statements
}

expression:

A managed array expression or collection. The compiler must be able to convert the collection element from Object to the identifier type. expression evaluates to a type that implements IEnumerable, IEnumerable, or a type that defines a GetEnumerator method. In the latter case, GetEnumerator should either return a type that implements IEnumerator or declares all the methods defined in IEnumerator.

Once again, you have a raw pointer, so it will not work.

Upvotes: 2

Related Questions