Why Is this Function For Array Size Not Working?

So I was just trying to get this function to work for array sizes why wouldn't this work? I know I'm doing something stupid also what could be done for a function that does this instead?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
using namespace std;

int Get_Int_Array_Length(int test[])
{
	int size = sizeof(test) / sizeof(int);
	return size;
}

int main()
{
	int li[10];
	li[0] = 5;
	li[1] = 6;

	cout << Get_Int_Array_Length(li) << endl;

	system("PAUSE");
	return 0;
}
When an array is passed by value to a function then it is converted to a pointer to its first element. So the following function declarattions are equivalent and declare the same function:

int Get_Int_Array_Length( int test[20] );

int Get_Int_Array_Length( int test[10] );

int Get_Int_Array_Length( int test[5] );

int Get_Int_Array_Length( int test[] );

int Get_Int_Array_Length ( int *test );

sizeof ( int * ) usually equal to 4 in 32-bit systems or 8 in 64-bit systems.
Thanks vlad. Well this is a good learning lesson for me then I've been playing around with it. How then would you output an arrays length of variable size in a function like that?
There are two approaches. Either you will pass an array by reference or you will use a second parameter that will contain the size of the array.

For example

1
2
3
4
5
template <size_t N>
size_t Get_Int_Array_Length( int ( &test )[N])
{
	return N;
}



or

1
2
3
4
size_t Get_Int_Array_Length( int test[], size_t n )
{
	return n;
}


You can use the both functions (template and non-template) in the same code.
For example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

template <size_t N>
size_t Get_Int_Array_Length( int ( &test )[N])
{
	return N;
}

size_t Get_Int_Array_Length( int test[], size_t n )
{
	return n;
}

int main()
{
   int a[20];

   std::cout << Get_Int_Array_Length( a ) << " == " << Get_Int_Array_Length( a, 20 ) << std::endl;

   return 0;
}
Last edited on
Thanks vlad from moscow. So I know size_t represents the size of an object in byte sized but I don't get how this code works i.e.

1
2
3
4
5
template <size_t N>
size_t Get_Int_Array_Length( int ( &test )[N])
{
	return N;
}


It does obviously work but why listen to what's going on in my head here so I understand it. So You are using a template which I understand so it could technically be any datatype correct not just an int?

And you have a reference its memory address with &test but then what's then int(&test)[N] so it's like an array it would seem of arrays almost or something? I just don't get that?

I thought with templates you declared the type later with something like <int> in replacement of T or whatever your data was? I'm just not seeing how this is working? Thanks in advance friend.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iterator>

template< typename T, std::size_t N >
inline constexpr std::size_t size( T (&) [N] ) { return N ; }
// type of the (unnamed) parameter is 'reference to array of N objects of type T'

template< typename T >
inline auto size( const T& seq ) -> decltype( seq.size() )
{ return seq.size() ; }

#include <list>
#include <iostream>

int main()
{
    const char cstr[] = "abcdefgh" ;
    std::cout << size(cstr) << '\n' ;

    std::list<int> lst( cstr, cstr+size(cstr)-1 ) ;
    std::cout << size(lst) << '\n' ;

    double dbl[ size(cstr) * 2 ] ; // constexpr
    std::cout << size(dbl) << '\n' ;
}


http://liveworkspace.org/code/2kwRM$0
@adn258
hat's then int(&test)[N] so it's like an array it would seem of arrays almost or something? I just don't get that?


It is a reference to an array of type int[N].
Compare

int ( *test )[N] - pointer to an array of type int[N]
int ( &test )[N] - reference to an array of type int[N]
Last edited on
See I didn't know you could do that I thought that you had to declare templates using the datatype for each template typename later within <> like <string for T which does work like

1
2
3
4
5
6
7
template <typename T, size_t N>
size_t size(T (&)[N]) {return N; }
	

string pop[5];
cout << size<string>(pop) << endl;


but you are not using that with N so apparently you don't have to do that with N right or? I'm still a bit confused
I thought that you had to declare templates using the datatype for each template typename later within <>


The compiler is often able to determine that automatically, so you do not always have to specify that. You only have to specify it when the compiler is unable to.
@adn258
but you are not using that with N so apparently you don't have to do that with N right or? I'm still a bit confused


In your original post you are speaking about an array of type int[]. Even your function was named as Get_Int_Array_Length. So there is no need to introduce a template parameter for the type of array elements. The only template parameter that is needed is the parameter for the size of an array.
Last edited on
Vlad from moscow thanks man. See this is a little but confusing because I'm used to using generics in C# more than templates in C++ and while they have similarities you can't do that in C# like (&) [N] so it looks like in in C++ you can do almost anything with templates like that? That's amazing
Topic archived. No new replies allowed.