C++ for each With a Pointer - c++

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;
}

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.

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.

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...

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.

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.

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!

Related

std::array vs array performance

If I want to build a very simple array like:
int myArray[3] = {1,2,3};
Should I use std::array instead?
std::array<int, 3> a = {{1, 2, 3}};
What are the advantages of using std::array over usual ones? Is it more performant? Just easier to handle for copy/access?
What are the advantages of using std::array over usual ones?
It has friendly value semantics, so that it can be passed to or returned from functions by value. Its interface makes it more convenient to find the size, and use with STL-style iterator-based algorithms.
Is it more performant ?
It should be exactly the same. By definition, it's a simple aggregate containing an array as its only member.
Just easier to handle for copy/access ?
Yes.
A std::array is a very thin wrapper around a C-style array, basically defined as
template<typename T, size_t N>
struct array
{
T _data[N];
T& operator[](size_t);
const T& operator[](size_t) const;
// other member functions and typedefs
};
It is an aggregate, and it allows you to use it almost like a fundamental type (i.e. you can pass-by-value, assign etc, whereas a standard C array cannot be assigned or copied directly to another array). You should take a look at some standard implementation (jump to definition from your favourite IDE or directly open <array>), it is a piece of the C++ standard library that is quite easy to read and understand.
std::array is designed as zero-overhead wrapper for C arrays that gives it the "normal" value like semantics of the other C++ containers.
You should not notice any difference in runtime performance while you still get to enjoy the extra features.
Using std::array instead of int[] style arrays is a good idea if you have C++11 or boost at hand.
Is it more performant ?
It should be exactly the same. By definition, it's a simple aggregate containing an array as its only member.
The situation seems to be more complicated, as std::array does not always produce identical assembly code compared to C-array depending on the specific platform.
I tested this specific situation on godbolt:
#include <array>
void test(double* const C, const double* const A,
const double* const B, const size_t size) {
for (size_t i = 0; i < size; i++) {
//double arr[2] = {0.e0};//
std::array<double, 2> arr = {0.e0};//different to double arr[2] for some compiler
for (size_t j = 0; j < size; j++) {
arr[0] += A[i] * B[j];
arr[1] += A[j] * B[i];
}
C[i] += arr[0];
C[i] += arr[1];
}
}
GCC and Clang produce identical assembly code for both the C-array version and the std::array version.
MSVC and ICPC, however, produce different assembly code for each array version. (I tested ICPC19 with -Ofast and -Os; MSVC -Ox and -Os)
I have no idea, why this is the case (I would indeed expect exactly identical behavior of std::array and c-array). Maybe there are different optimization strategies employed.
As a little extra:
There seems to be a bug in ICPC with
#pragma simd
for vectorization when using the c-array in some situations
(the c-array code produces a wrong output; the std::array version works fine).
Unfortunately, I do not have a minimal working example for that yet, since I discovered that problem while optimizing a quite complicated piece of code.
I will file a bug-report to intel when I am sure that I did not just misunderstood something about C-array/std::array and #pragma simd.
std::array has value semantics while raw arrays do not. This means you can copy std::array and treat it like a primitive value. You can receive them by value or reference as function arguments and you can return them by value.
If you never copy a std::array, then there is no performance difference than a raw array. If you do need to make copies then std::array will do the right thing and should still give equal performance.
You will get the same perfomance results using std::array and c array
If you run these code:
std::array<QPair<int, int>, 9> *m_array=new std::array<QPair<int, int>, 9>();
QPair<int, int> *carr=new QPair<int, int>[10];
QElapsedTimer timer;
timer.start();
for (int j=0; j<1000000000; j++)
{
for (int i=0; i<9; i++)
{
m_array->operator[](i).first=i+j;
m_array->operator[](i).second=j-i;
}
}
qDebug() << "std::array<QPair<int, int>" << timer.elapsed() << "milliseconds";
timer.start();
for (int j=0; j<1000000000; j++)
{
for (int i=0; i<9; i++)
{
carr[i].first=i+j;
carr[i].second=j-i;
}
}
qDebug() << "QPair<int, int> took" << timer.elapsed() << "milliseconds";
return 0;
You will get these results:
std::array<QPair<int, int> 5670 milliseconds
QPair<int, int> took 5638 milliseconds
Mike Seymour is right, if you can use std::array you should use it.

C++ iterate an array of integers whose size is unknown?

I have the following array:
int* myArray = new int[45];
If I wanted to iterate each element without knowing the actual size of the array, I would need to use a for_each?
If so, then how would you write the for_each? I was looking over the following site and reading up on for_each but can't figure out how to put this together.
http://www.cplusplus.com/reference/algorithm/for_each/
Update: A for_each is not a good choice in this case, due to the fact that the size of the array has to be known. vectors are the proper way to accomplish such task. My reason for using arrays, in this case, was for learning purposes. if this was a serious project I would move to something such as Lists/Vectors.
Note when the question was first posted, the array in question was declared as
int myArray[45];
This answer deals with that particular case.
If you have C++11 support, you can use a range based loop:
for (int& i : myArray) {
std::cout << i << "\n";
}
C++11 also provides std::begin and std::end, which you can use with a fixed size array to obtain iterators:
std::for_each(std::begin(myArray), std::end(myArray), <func>);
Another option, which works for C++03 and you are dealing with fixed size arrays, is to define a function template:
// taken a fixed size array by reference and loop over it
template <typename T, unsigned int N>
void array_for_each( T (&a)[N]) {
for (unsigned int i = 0; i < N; ++i) {
// do something with array elements
std::cout << a[i] << " ";
}
}
int main() {
int a[5];
array_for_each(a);
}
If you use MSVC (Microsoft Visual C++), you can use "for each."
for each(int i in arr) {
cout << i << ' ' << endl;
}
NOTE: This only works in the block of code the array is declared in.
If not, you can also use the new range-based for loop in the C++11 standard.
for(int i : arr) {
cout << i << ' ' << endl;
}
If you're intent upon the std::for_each:
for_each(arr,arr + 10,[] (int i) {
cout << i << ' ' << endl;
});
NOTE: This requires knowledge of the size of the array (in this example, 10).
You could use a for_each. In this case, you have allocated space for 45 elements in your array, but since it is NULL, you'd probably get a segfault if you tried to do anything. You either need to hold a value of the array, or use something like sizeof(myArray)/sizeof(myArray[0]) (which has its own problems).
Anyway, for a for_each here, if we actually had 45 elements:
std::for_each(myArray, myArray + 45, <func>);
Anyway, this is part of the reason to use vectors: .begin() and .end() reduces errors with using incorrect indexing.
You have described an array of int, not a class that implements a InputIterator, which is what the for_each is designed for, even though you can use it to iterate an array, but you need to know the size of the array to iterate it.
If you want to use for_each you need to use a vector, list, or implement a class that keeps track of the number of elements it contains. IMO it is much easier to just use a vector
If you want to just iterate your current array, assuming it is 0 terminated:
for(int *value = myArray; *value != 0; ++value)
printf("%d\n", *value);
Or, you can use indexes:
for(int index = 0; myArray[index] != 0; ++index)
printf("%d\n", myArray[index]);
IMO the pointer method is cleaner.
This code is still dangerous though, you should either keep track of the number of records in a seperate variable, or use a vector.

C++ Sorting Function

So I'm trying to get a sort function to work. It should sort by firstname, but if the first names are the same it should sort by last names. I keep getting an error in mySort() that says "unexpected primary-expression before ')' token" on line where inOrder = arr. What's happening to this and how can I fix it? I need to pass my objects into a function in a seperate class. I'll link them in pastebin.
Here's the driver
#include <iostream>
#include <fstream>
#include <string>
#include "phoneEntry.h"
using namespace std;
void mySort(PhoneEntry& arr, int size)
{
bool inOrder = false;
for (int i = size - 1; i > 0 && !inOrder; i--)
{
inOrder = true;
for (int j = 0; j < i; j++)
{
inOrder = arr.alphaGreater(arr&);
}
}
};
int main()
{
const int MAXNUM = 500;
PhoneEntry entry[MAXNUM];
ifstream filezilla;
filezilla.open("phone.txt");
int count = 0;
if(filezilla)
{
while(count < MAXNUM && entry[count].readEntry(filezilla))
{
count++;
}
mySort(entry&, count);
for(int i = 0; i < count; i++)
{
entry[i].writeEntry(cout) << endl;
}
}
else
{
cout << "Four Oh Four - File Not Found" << endl;
}
return 0;
}
Phone Entry Header
Phone Number Header
Sorting Text (http://pastebin.com/HE8Rsmbg)
You want to pass a reference, so the argument has to be defined as call-by-reference in the function definition/declaration, which is already done:
bool PhoneEntry::alphaGreater(const PhoneEntry& item) const;
As you can see, PhoneEntry::alphaGreater takes a constant PhoneEntry reference. So simply use
inOrder = arr.alphaGreater(arr);
There are several things wrong with your code. The first, the one the
compiler is complaining about, is that there is no postfix operator &
in C++. I don't know exactly what you're trying to do with it, or what
you think it means, but it doesn't exist in C++.
The second is that mySort takes a reference to a single PhoneEntry;
you have an array of PhoneEntry, so you'll have to select one to pass
it. Except that the name of the function and the fact that you pass a
count as well suggest that you really want to pass an array.
And I can't figure out what mySort is supposed to be doing. It
certainly doesn't sort anything; in fact, it seems to be fundamentally
an expensive no-op, since it doesn't return anything, it doesn't modify
arr, and it doesn't access or modify any global state.
For the rest, you need more error checking on the input (did the open
succeed, etc.), and you really should be using std::vector, rather
than a C style array. (There are cases where C style arrays are
appropriate, but this isn't one of them.)
More fundamentally, I'd suggest you get a good book and study it. (I'd
recommend Stroustrup's Programming Principles and Practice Using C++.)
You can't write a program in any language without knowing at least the
most basic fundamentals and basic syntax.
you can pass it as pointers also

C++ cast vector type in place

Is it possible to do this without creating new data structure?
Suppose we have
struct Span{
int from;
int to;
}
vector<Span> s;
We want to get an integer vector from s directly, by casting
vector<Span> s;
to
vector<int> s;
so we could remove/change some "from", "to" elements, then cast it back to
vector<Span> s;
This is not really a good idea, but I'll show you how.
You can get a raw pointer to the integer this way:
int * myPointer2 = (int*)&(s[0]);
but this is really bad practice because you can't guarantee that the span structure doesn't have any padding, so while it might work fine for me and you today we can't say much for other systems.
#include <iostream>
#include <vector>
struct Span{
int from;
int to;
};
int main()
{
std::vector<Span> s;
Span a = { 1, 2};
Span b = {2, 9};
Span c = {10, 14};
s.push_back(a);
s.push_back(b);
s.push_back(c);
int * myPointer = (int*)&(s[0]);
for(int k = 0; k < 6; k++)
{
std::cout << myPointer[k] << std::endl;
}
return 0;
}
As I said, that hard reinterpret cast will often work but is very dangerous and lacks the cross-platform guarantees you normally expect from C/C++.
The next worse thing is this, that will actually do what you asked but you should never do. This is the sort of code you could get fired for:
// Baaaad mojo here: turn a vector<span> into a vector<int>:
std::vector<int> * pis = (std::vector<int>*)&s;
for ( std::vector<int>::iterator It = pis->begin(); It != pis->end(); It++ )
std::cout << *It << std::endl;
Notice how I'm using a pointer to vector and pointing to the address of the vector object s. My hope is that the internals of both vectors are the same and I can use them just like that. For me, this works and while the standard templates may luckily require this to be the case, it is not generally so for templated classes (see such things as padding and template specialization).
Consider instead copying out an array (see ref 2 below) or just using s1.from and s[2].to.
Related Reading:
Are std::vector elements guaranteed to be contiguous?
How to convert vector to array in C++
If sizeof(Span) == sizeof(int) * 2 (that is, Span has no padding), then you can safely use reinterpret_cast<int*>(&v[0]) to get a pointer to array of int that you can iterate over. You can guarantee no-padding structures on a per-compiler basis, with __attribute__((__packed__)) in GCC and #pragma pack in Visual Studio.
However, there is a way that is guaranteed by the standard. Define Span like so:
struct Span {
int endpoints[2];
};
endpoints[0] and endpoints[1] are required to be contiguous. Add some from() and to() accessors for your convenience, if you like, but now you can use reinterpret_cast<int*>(&v[0]) to your heart’s content.
But if you’re going to be doing a lot of this pointer-munging, you might want to make your own vector-like data structure that is more amenable to this treatment—one that offers more safety guarantees so you can avoid shot feet.
Disclaimer: I have absolutely no idea about what you are trying to do. I am simply making educated guesses and showing possible solutions based on that. Hopefully I'll guess one right and you won't have to do crazy shenanigans with stupid casts.
If you want to remove a certain element from the vector, all you need to do is find it and remove it, using the erase function. You need an iterator to your element, and obtaining that iterator depends on what you know about the element in question. Given std::vector<Span> v;:
If you know its index:
v.erase(v.begin() + idx);
If you have an object that is equal to the one you're looking for:
Span doppelganger;
v.erase(std::find(v.begin(), v.end(), doppelganger));
If you have an object that is equal to what you're looking for but want to remove all equal elements, you need the erase-remove idiom:
Span doppelganger;
v.erase(std::remove(v.begin(), v.end(), doppelganger)),
v.end());
If you have some criterion to select the element:
v.erase(std::find(v.begin(), v.end(),
[](Span const& s) { return s.from == 0; }));
// in C++03 you need a separate function for the criterion
bool starts_from_zero(Span const& s) { return s.from == 0; }
v.erase(std::find(v.begin(), v.end(), starts_from_zero));
If you have some criterion and want to remove all elements that fit that criterion, you need the erase-remove idiom again:
v.erase(std::remove_if(v.begin(), v.end(), starts_from_zero)),
v.end());

Passing a list of numbers to a function in C++ without building array first?

I'm trying to build a function that accepts an array in the following manner:
int inCommon = findCommon({54,56,2,10}, 4);
int findCommon(int nums[], int len){
for(int i=0; i<len; i++) cout<<nums[i]<<endl;
return 1;
}
Note, that's not actually what my function does, but I do loop through the array. I'm just trying to determine if it's possible to pass an array like {54,56,2,10} instead of having to create an array and pass it? (like this:
int theArray[]= {54,56,2,10};
int inCommon = findCommon(theArray,4);
This is not possible at the time. However, in the next C++ standard C++0x, this will be done using initalizer lists:
int findCommon(std::initializer_list<int> nums)
{
std::initializer_list<int>::iterator it;
for (it = nums.begin() ; it != nums.end() ; ++it)
{
std::cout << *it << std::endl;
}
return 1;
}
See this presentation from Bjarne Stroustrup, and this article from Wikipedia
If you want to try C++0x features, you can check the last versions of gcc, that supports some of them.
You need C++0x!
http://en.wikipedia.org/wiki/C%2B%2B0x#Initializer_lists
No, I believe {} may only be used to initialize an array.
You can do what you want to do using variable argument lists.
no. It is impossible.
But you can create something like template T* arrayCreator(...) function which will create your array,
Or array wrapper with constructor with unspecified arguments count.
Or create object which will have overloaded operator coma or << and will create your array, findCommon( arrCreator() << 1 << 2 << 3 << 5, other parammeters ) - this method more type safe
Or waiting C++0x implementation.