Hello everyone,


In the following code, how GetArrayLength(arr1) is matched to template
function size_t GetArrayLength(const T(&arr)[size])? My confusion is how arr1
is matched to const T(&arr)[size]? I have tried to change const T(&arr)[size]
to const T(arr)[size]) but it does not work.

[Code]
template<size_t size, typename T>
size_t GetArrayLength(const T(&arr)[size])
{
return size;
}

int main()
{
char arr1[] = "Hello World";
std::cout << GetArrayLength(arr1) << std::endl;

return 0;
}
[/Code]


thanks in advance,
George

Re: template function issue by Ulrich

Ulrich
Wed Dec 12 04:01:55 PST 2007

George wrote:
> In the following code, how GetArrayLength(arr1) is matched to template
> function size_t GetArrayLength(const T(&arr)[size])? My confusion is how
> arr1 is matched to const T(&arr)[size]? I have tried to change const
> T(&arr)[size] to const T(arr)[size]) but it does not work.

Define "does not work". Seriously, you have been asking questions here long
enough to have learned that a good error description is half the way to the
goal. It also shows that you have been doing your homework.

> template<size_t size, typename T>
> size_t GetArrayLength(const T(&arr)[size])
> {
> return size;
> }

You can't pass an array to a function. Even if the function declaration
seems to suggest that it receives an array, it is in fact a pointer:

void foo( int x[4]);

is in fact the same as

void foo( int* x);

This is dangerous, because passing by value doesn't modify the parameters at
the caller's side, but since this isn't pass-by-value the parameters can be
modified!

Now, what you can do is to pass a reference-to-an-array to a function. In
that case, this does not decay to something like a pointer or a reference
to a pointer.

I hope this now also makes it clear why this can't work with a template: The
template requires parameters it can't deduce from the function parameters
(like the array size when there is no array passed around).

Uli


Re: template function issue by George

George
Wed Dec 12 05:10:01 PST 2007

Thanks Uli,


I do not quite understand why arr is a reference to an array type?

> pass a reference-to-an-array to a function

In GetArrayLength(const T(&arr)[size]), I have tried to use,

typeid(arr).name(),

and the result is,

char const(*) [12]

You mean char const(*) [12] is the same as reference to an array type? I am
confused. :-)

BTW: it is not homework. I am learning source codes from other people. :-)


regards,
George

"Ulrich Eckhardt" wrote:

> George wrote:
> > In the following code, how GetArrayLength(arr1) is matched to template
> > function size_t GetArrayLength(const T(&arr)[size])? My confusion is how
> > arr1 is matched to const T(&arr)[size]? I have tried to change const
> > T(&arr)[size] to const T(arr)[size]) but it does not work.
>
> Define "does not work". Seriously, you have been asking questions here long
> enough to have learned that a good error description is half the way to the
> goal. It also shows that you have been doing your homework.
>
> > template<size_t size, typename T>
> > size_t GetArrayLength(const T(&arr)[size])
> > {
> > return size;
> > }
>
> You can't pass an array to a function. Even if the function declaration
> seems to suggest that it receives an array, it is in fact a pointer:
>
> void foo( int x[4]);
>
> is in fact the same as
>
> void foo( int* x);
>
> This is dangerous, because passing by value doesn't modify the parameters at
> the caller's side, but since this isn't pass-by-value the parameters can be
> modified!
>
> Now, what you can do is to pass a reference-to-an-array to a function. In
> that case, this does not decay to something like a pointer or a reference
> to a pointer.
>
> I hope this now also makes it clear why this can't work with a template: The
> template requires parameters it can't deduce from the function parameters
> (like the array size when there is no array passed around).
>
> Uli
>
>

Re: template function issue by Doug

Doug
Wed Dec 12 09:22:32 PST 2007

On Wed, 12 Dec 2007 05:10:01 -0800, George
<George@discussions.microsoft.com> wrote:

>I do not quite understand why arr is a reference to an array type?

The parameter "arr" has the type, "reference to array of 'size' T". To
understand why, you have to some basic knowledge of the declaration syntax.
Do you have a specific question about the syntax?

>In GetArrayLength(const T(&arr)[size]), I have tried to use,
>
>typeid(arr).name(),
>
>and the result is,
>
>char const(*) [12]
>
>You mean char const(*) [12] is the same as reference to an array type?

No, that means, "pointer to array of 12 const char", and it's very
different. For example, the size of that type is sizeof(pointer), while
sizeof(arr) is the size of the referent, i.e. the array, i.e.
size*sizeof(T).

>I am confused. :-)

The type_info::name function doesn't have to give useful information, so it
should not be relied upon to explore the type system. It would be a
problem, though, if typeid(arr) == typeid(ptr), where ptr has the pointer
type you introduced above.

--
Doug Harrison
Visual C++ MVP

Re: template function issue by George

George
Wed Dec 12 18:49:02 PST 2007

Thanks Doug,


Why GetArrayLength(const T(&arr)[size]) works, but

GetArrayLength(const T(arr)[size]) -- I removed & does not work?


regards,
George

"Doug Harrison [MVP]" wrote:

> On Wed, 12 Dec 2007 05:10:01 -0800, George
> <George@discussions.microsoft.com> wrote:
>
> >I do not quite understand why arr is a reference to an array type?
>
> The parameter "arr" has the type, "reference to array of 'size' T". To
> understand why, you have to some basic knowledge of the declaration syntax.
> Do you have a specific question about the syntax?
>
> >In GetArrayLength(const T(&arr)[size]), I have tried to use,
> >
> >typeid(arr).name(),
> >
> >and the result is,
> >
> >char const(*) [12]
> >
> >You mean char const(*) [12] is the same as reference to an array type?
>
> No, that means, "pointer to array of 12 const char", and it's very
> different. For example, the size of that type is sizeof(pointer), while
> sizeof(arr) is the size of the referent, i.e. the array, i.e.
> size*sizeof(T).
>
> >I am confused. :-)
>
> The type_info::name function doesn't have to give useful information, so it
> should not be relied upon to explore the type system. It would be a
> problem, though, if typeid(arr) == typeid(ptr), where ptr has the pointer
> type you introduced above.
>
> --
> Doug Harrison
> Visual C++ MVP
>

Re: template function issue by Tim

Tim
Wed Dec 12 22:59:43 PST 2007

George <George@discussions.microsoft.com> wrote:
>
>Why GetArrayLength(const T(&arr)[size]) works, but
>
>GetArrayLength(const T(arr)[size]) -- I removed & does not work?

Ulrich already answered that question. You can't pass an array to a
function. You can pass is the address of an array, either by reference or
by pointer.
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Re: template function issue by George

George
Wed Dec 12 23:16:00 PST 2007

Thanks for your clarification, Tim!


But, to pass an array is ok in C++. Can you try the following code please?

#include <iostream>

using namespace std;

void Foo1 (char input[12])
{
std::cout << typeid(input).name() << endl; // output char*

input [0] = '1';

return;
}

void Foo2 (char (&input) [12])
{
std::cout << typeid(input).name() << endl; // output char [12]

input [0] = '2';

return;
}

void Foo3 (char* input)
{
input [0] = '3';

return;
}

int main()
{
char buf[] = "Hello World";

Foo1 (buf);

cout << buf << endl; //output "1ello World"

Foo2 (buf);

cout << buf << endl; //output "2ello World"

Foo3 (buf);

cout << buf << endl; //output "3ello World"

return 0;
}


regards,
George

"Tim Roberts" wrote:

> George <George@discussions.microsoft.com> wrote:
> >
> >Why GetArrayLength(const T(&arr)[size]) works, but
> >
> >GetArrayLength(const T(arr)[size]) -- I removed & does not work?
>
> Ulrich already answered that question. You can't pass an array to a
> function. You can pass is the address of an array, either by reference or
> by pointer.
> --
> Tim Roberts, timr@probo.com
> Providenza & Boekelheide, Inc.
>

Re: template function issue by Ondrej

Ondrej
Thu Dec 13 01:06:33 PST 2007

> But, to pass an array is ok in C++. Can you try the following code
please?

It is OK, but the language defines such passing is implemented in such a
way the pointer to the array is passed instead, not the array value,
which is what Uli described in his first reply, and which is evidenced
by your sample. You can see Foo1 modified the input, meaning the array
was not passed by its value, but rather by a pointer to its members -
actually instead of char input[12] the parameter is passed as char *input.

I think you could perhaps consider reading some good book about C++
language, where basics like this would be described?

Ondrej

George napsal(a):
> Thanks for your clarification, Tim!
>
>
> But, to pass an array is ok in C++. Can you try the following code please?
>
> #include <iostream>
>
> using namespace std;
>
> void Foo1 (char input[12])
> {
> std::cout << typeid(input).name() << endl; // output char*
>
> input [0] = '1';
>
> return;
> }
>
> void Foo2 (char (&input) [12])
> {
> std::cout << typeid(input).name() << endl; // output char [12]
>
> input [0] = '2';
>
> return;
> }
>
> void Foo3 (char* input)
> {
> input [0] = '3';
>
> return;
> }
>
> int main()
> {
> char buf[] = "Hello World";
>
> Foo1 (buf);
>
> cout << buf << endl; //output "1ello World"
>
> Foo2 (buf);
>
> cout << buf << endl; //output "2ello World"
>
> Foo3 (buf);
>
> cout << buf << endl; //output "3ello World"
>
> return 0;
> }
>
>
> regards,
> George
>
> "Tim Roberts" wrote:
>
>> George <George@discussions.microsoft.com> wrote:
>>> Why GetArrayLength(const T(&arr)[size]) works, but
>>>
>>> GetArrayLength(const T(arr)[size]) -- I removed & does not work?
>> Ulrich already answered that question. You can't pass an array to a
>> function. You can pass is the address of an array, either by reference or
>> by pointer.
>> --
>> Tim Roberts, timr@probo.com
>> Providenza & Boekelheide, Inc.
>>

Re: template function issue by George

George
Thu Dec 13 01:31:01 PST 2007

Thanks for your confirmation, Ondrej!


regards,
George

"Ondrej Spanel" wrote:

> > But, to pass an array is ok in C++. Can you try the following code
> please?
>
> It is OK, but the language defines such passing is implemented in such a
> way the pointer to the array is passed instead, not the array value,
> which is what Uli described in his first reply, and which is evidenced
> by your sample. You can see Foo1 modified the input, meaning the array
> was not passed by its value, but rather by a pointer to its members -
> actually instead of char input[12] the parameter is passed as char *input.
>
> I think you could perhaps consider reading some good book about C++
> language, where basics like this would be described?
>
> Ondrej
>
> George napsal(a):
> > Thanks for your clarification, Tim!
> >
> >
> > But, to pass an array is ok in C++. Can you try the following code please?
> >
> > #include <iostream>
> >
> > using namespace std;
> >
> > void Foo1 (char input[12])
> > {
> > std::cout << typeid(input).name() << endl; // output char*
> >
> > input [0] = '1';
> >
> > return;
> > }
> >
> > void Foo2 (char (&input) [12])
> > {
> > std::cout << typeid(input).name() << endl; // output char [12]
> >
> > input [0] = '2';
> >
> > return;
> > }
> >
> > void Foo3 (char* input)
> > {
> > input [0] = '3';
> >
> > return;
> > }
> >
> > int main()
> > {
> > char buf[] = "Hello World";
> >
> > Foo1 (buf);
> >
> > cout << buf << endl; //output "1ello World"
> >
> > Foo2 (buf);
> >
> > cout << buf << endl; //output "2ello World"
> >
> > Foo3 (buf);
> >
> > cout << buf << endl; //output "3ello World"
> >
> > return 0;
> > }
> >
> >
> > regards,
> > George
> >
> > "Tim Roberts" wrote:
> >
> >> George <George@discussions.microsoft.com> wrote:
> >>> Why GetArrayLength(const T(&arr)[size]) works, but
> >>>
> >>> GetArrayLength(const T(arr)[size]) -- I removed & does not work?
> >> Ulrich already answered that question. You can't pass an array to a
> >> function. You can pass is the address of an array, either by reference or
> >> by pointer.
> >> --
> >> Tim Roberts, timr@probo.com
> >> Providenza & Boekelheide, Inc.
> >>
>