1

I have a struct:

typedef struct
{  
   int nNum; 
   string str;   
}KeyPair;

Let's say I initialize my struct:

KeyPair keys[] = 
{    {0, "tester"},  
     {2, "yadah"},  
     {0, "tester"} 
};  

I want to use the initialized values in a function. How do I pass this array struct as a function parameter?

I have:

FetchKeys( KeyPair *pKeys)
{
     //get the contents of keys[] here...   
}
Owen
  • 4,063
  • 17
  • 58
  • 78

8 Answers8

5

How about?

template<int N> void FetchKeys(KeyPair const (&r)[N]){}

EDIT 2:

Or even

template<int N> void FetchKeys(KeyPair const (*p)[N])

with the call as

FetchKeys(&keys);
Chubsdad
  • 24,777
  • 4
  • 73
  • 129
4

You can do it as @MSalters mentioned, or you can create a std::vector<KeyPair> and pass it to the function. Here is a sample code:

using namespace std;

struct KeyPair 
{ 
   int nNum;
   string str;  
};

void fetchKeys(const vector<KeyPair>& keys)
{
    //Go through elements of the vector
    vector<KeyPair>::const_iterator iter = keys.begin();
    for(; iter != keys.end(); ++iter)
    {
        const KeyPair& pair = *iter;

    }
}



int main()
{
    KeyPair keys[] = {{0, "tester"}, 
                   {2, "yadah"}, 
                   {0, "tester"}
                  }; 

    //Create a vector out of the array you are having
    vector<KeyPair> v(keys, keys + sizeof(keys)/sizeof(keys[0]));

    //Pass this vector to the function. This is safe as vector knows
    //how many element it contains
    fetchKeys(v);
    return 0;

}
Naveen
  • 74,600
  • 47
  • 176
  • 233
  • Indeed. Never use an array unless you are forced to (for instance, because of a legacy function interface). – Gorpik Nov 26 '10 at 11:20
3

Should be

// Definition
void FetchKeys( KeyPair *pKeys, int nKeys)
{
     //get the contents of keys[] here...   
}
// Call
FetchKeys(keys, sizeof(keys)/sizeof(keys[0]));
MSalters
  • 173,980
  • 10
  • 155
  • 350
  • 7
    I feel like I'm pissing into the ocean with how often I have to say this but please use `size_t` instead of `int` to represent object sizes and array indices. – Chris Lutz Nov 26 '10 at 10:49
  • 2
    #define countOf(a) (sizeof(a) / sizeof(*(a))) – tato Nov 26 '10 at 10:50
  • 1
    @tato no need to use #define here, you can use a template to do it: template size_t countOf(T (&arr)[N] ) return N; and does not have the side effect of accidentally passing in a pointer instead of an array. – CashCow Nov 26 '10 at 11:21
1

You just callFetchKeys(keys);

EDIT

Pay attention to declare FetchKeys' return type.

EDIT 2

If you also need the number of items, you add size as FetchKeys input parameters:

void FetchKeys(KeyPair*, size_t size);

and call FetchKeys(keys, sizeof(keys)/sizeof(*keys));

BTW, state all your question by editing your first post if you can.

Simone
  • 11,655
  • 1
  • 30
  • 43
1

In c/c++ the name of the array (of any type) represents the address of the first element of the array, so keys and &keys [0] are same. You can pass any one of them for KeyPair*.

Rajivji
  • 305
  • 1
  • 2
  • The correct wording is that in C/C++ arrays **decay** into pointers to the first element quite easily. That is not the same as claiming that *the name of the array represents the address of the first element* --the name of the array represents the array, and that **is not** a pointer to the first element. Take a look at @Chubsdad answer for a real use case (C++ only) where your interpretation would fail. – David Rodríguez - dribeas Nov 26 '10 at 11:33
  • For a C test, try: `void foo( int (*array)[5] ) {} int main() { int array[5] = {0}; foo( &array ); int array2[2] = {0}; /*foo(&array2)*/ }` The code will compile for the first case as the array has 5 elements, but will fail in the second (commented out) case as the number of elements differ. The test verifies that the array is not a pointer to the first element, but has the size information --which is only available at compile time, and before the array *decays* into a pointer. – David Rodríguez - dribeas Nov 26 '10 at 11:39
1

Depending on what you want to do you can even use boost range and pass it to function as a pair of iterators:

void FetchKeys(KeyPair *begin, KeyPair *end)
FetchKeys(boost::begin(keys), boost::end(keys));
Tomek
  • 4,554
  • 1
  • 19
  • 19
0

See this answer: How can I pass an array by reference to a function in C++?

Wrap it in a structure, nice and easy..

#include <iostream>

struct foo
{
  int a;
  int b;
};

template <typename _T, size_t _size>
struct array_of
{
  static size_t size() { return _size; }
  _T data[_size];
};

template <typename _at>
void test(_at & array)
{
  cout << "size: " << _at::size() << std::endl;
}

int main(void)
{
  array_of<foo, 3> a = {{ {1,2}, {2,2}, {3,2} }};

  test(a);

}

EDIT: URGH, I can't see the toolbar to format the code correctly, hopefully the tags works..

Community
  • 1
  • 1
Nim
  • 33,299
  • 2
  • 62
  • 101
  • Just a quick question; in C, identifiers starting with an underscore followed by a capital letter (i.e. `_T`) are reserved and using them results in undefined behaviour. Do you know whether C++ has this same restriction, even for templates? – dreamlax Nov 26 '10 at 11:20
  • @dreamlax: See ["What are the rules about using an underscore in a C++ identifier?"](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier). Identifiers starting with an underscore followed by an uppercase letter are reserved in any scope. – Georg Fritzsche Nov 26 '10 at 11:23
  • @dreamlax, thanks, there was something odd going on and I couldn't format/comment etc. now seems to be okay... With respect to your question, I was just being lazy... – Nim Nov 26 '10 at 11:40
0

i use VS 2008, and this works fine for me.

#include "stdafx.h"

typedef struct
{  
   int nNum; 
   CString str;   
}KeyPair;

void FetchKeys( KeyPair *pKeys);
int _tmain(int argc, _TCHAR* argv[])
{

    KeyPair keys[] = 
{    {0, _T("tester")},  
     {2, _T("yadah")},  
     {0, _T("tester")} 
};

    FetchKeys(keys); //--> just pass the initialized variable.
    return 0;
}

void FetchKeys(KeyPair *pKeys)
{
    printf("%d, %s\n",pKeys[0].nNum, pKeys[0].str);

}

I don't understand the difficulty. correct me if i'm wrong. To keep it simple, i avoided using vectors, templates and etc. edit: to know size of struct, you can pass one more arg.

rplusg
  • 3,418
  • 6
  • 34
  • 49