11

I am new to C++ and I am writing the following code. I needed to iterate over all the addons in my calling function - testFunction. I know this works in C#, but this code is not working. Can anyone please point out the right way to do it in C++?

#include "stdafx.h"
#include <iostream>
#include "resource.h"

int testFunction(char* tester);
int _tmain()
{
    int mainProd=2;
    int Addons[]={7,8,9,10};

    testFunction(mainProd,Addons);


}
void testFunction(int mainProd,int addons[])
{
    for(int x = 0 ; addons.length;++x) ---- Not working 
    {
        std::cout<< addons[x];
    }
}

I tried to implement vector as below suggestions by you guys

#include "stdafx.h"
#include <iostream>
#include "resource.h"
#include <vector>

void testFunction(std::vector<int> addons);

int _tmain(int argc, _TCHAR* argv[])
{

    std::vector<int>  Addons ;
    for(int i = 0 ;i<10;++i)
    {
        Addons.push_back(i);
    }
     testFunction(Addons);
}

void testFunction(std::vector<int> addons)
{
    for(int i =0 ; i<addons.size();++i)
    {
        std::cout<<addons.at(i);
    }
}
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
junni lomo
  • 769
  • 3
  • 10
  • 15
  • 7
    Where did you get the idea that `.length` would work? Perhaps you need to pick [a better book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)? – R. Martinho Fernandes Jan 15 '13 at 13:21
  • What does your favourite C++ book say? – Christian Rau Jan 15 '13 at 13:24
  • 4
    fordward declare the correct version of testFunction too. – qPCR4vir Jan 15 '13 at 13:26
  • 1
    pass by reference the vector in order to avoid unnecessary copys `void testFunction(const std::vector &addons) // note the 'const' and the '&'` – PaperBirdMaster Jan 15 '13 at 14:46
  • 2
    `for(int i =0 ; i – Alex Chamberlain Jan 15 '13 at 15:27
  • @AlexChamberlain *is bad style* this argument has never convinced me. Is there a better one for this case (when we are not considering to use another contain than std::vector)? Note that C++11 does away with `begin` and `end` when using the range loop `for(auto i:addons)`. – Walter Jan 16 '13 at 16:48
  • @Walter C++11 doesn't do away with it; I for one think the range-for is horrible. It's mildly more efficient to use iterators directly for vectors, and significantly more efficient for other containers. Overall though, it is consistent. You can rip out your `std::vector` and use a `std::list` or `std::set` and have code that still works. – Alex Chamberlain Jan 16 '13 at 17:20
  • @AlexChamberlain Yes, I know this argument (as alluded to in my previous comment), it's much better than *bad style*. Btw, I didn't say C++11 does away with `begin` and `end` -- read my comment carefully! – Walter Jan 17 '13 at 12:36
  • Since you are using C++11, you can create your vector using list initialization: `std::vector Addons = {7,8,9,10};` – Paul Aug 28 '14 at 19:01

6 Answers6

20

An array (a raw array) decays into a pointer when passed as an argument to a function, so your array has no size information.

You need to pass the length of the array explicitly into the function to know it inside the function.

Alternatively, and better, use a std::vector and then you'll have the .size() always available when needed.

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
7

Apart from using vectors, as Tony suggests, you can use templates and pass the array by reference so that the compiler will deduce the array's size:

template<int N>
void testFunction(int mainProd,int (&addons)[N])
{
    for(int x = 0; x < N; ++x) // ---- working 
    {
        std::cout<< addons[x];
    }
}
Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
3

You're using concepts of C# in C++ but, even if we assume that both languages are similar, they're not equal.

The syntax for a ranged-for in C++ is the following:

for (type identifier : container) // note the ':', not ';'
{
    // do stuff
}

You can use this for flavour if you have a C++11 compiler.

Btw, it seems that you're using properties on your code:

for(int x = 0 ; addons.length;++x) // what is lenght?
{
    std::cout<< addons[x];
}

There's no such thing in C++, if you want to call an object method you need to call it as a function:

// assuming that the object 'addons' have a method
// named 'length'  that takes no parameters
addons.length();

But the addons variable isn't an object, is an array (take a look to this tutorial), so it doesn't have a method or property named length; if you need to know its length in order to iterate it you can use in some contexts the sizeof operator (see the tutorial for more information).

Let's suppose that addons were a container:

typedef std::vector<addon> Addons;
Addons addons;

If you want to iterate it using the C++11 range-for, you can write it as follows:

for (addon a : addons)
{
    // do stuff with a.
}

Hope it helps.

Community
  • 1
  • 1
PaperBirdMaster
  • 12,806
  • 9
  • 48
  • 94
2

If you were to use a std::vector or std::array, you could use std::foreach,

std::vector<int> addons = {7,8,9,10};
std::array<int, 4> addons = {7,8,9,10}; // Only use one of these...
std::foreach(addons.begin(), addon.end(), [](int i) {
    std::cout << i
});
Alex Chamberlain
  • 4,147
  • 2
  • 22
  • 49
1

Code is working with this

for (int i = 0; i < (end(array) - begin(array)); i++)

Return maximum size

Test whether array is empty

array::empty

Element of array

array::size

Array size

sizeof()
Vivek Malik
  • 165
  • 1
  • 10
1

If you don't want to use any STL container, you just need to pass the array by reference to the function. Problem here is that you can't define such argument without exact size of the array. This restriction you can overcome making the function as a template, defining the size as the template parameter:

#include <iostream>

template<int N>
void testFunction(int mainProd,int (&addons)[N])
{
    for(int x = 0 ; x < N; ++x)
    {
        std::cout<< addons[x];
    }
}

int main()
{
    int mainProd=2;
    int Addons[]={7,8,9,10};

    testFunction(mainProd,Addons);
    return 0;
}