Reference to array, NOT array of references!

J

JKop

template<class T>
inline T& NthArrayMember( T & (array[]),size_t i)
{
return array[i - 1];
}

template<class T>
inline const T& NthArrayMember( const T & (array[]),size_t i)
{
return array[i - 1];
}


G++: declaration of `array' as array of references


I've tried about five different parenthesis combinations, but I just can't
get a reference to an array!

It's to be used as so:

int main()
{
int blah[50];

NthArrayMember(blah,45) = 56; //45th member = 56

extern void SomeFunc(int);

SomeFunc( NthArrayMember(blah,34) ); //Passes 34th member

}


-JKop
 
J

JKop

Granted I get this to work, do you think the following
would be more efficent in that a temporary is unnecessary:

template<class T>
inline T& NthArrayMember( T & (array[]),size_t i)
{
return array[i -= 1]; //As opposed to just -
}
 
H

Howard

JKop said:
template<class T>
inline T& NthArrayMember( T & (array[]),size_t i)
{
return array[i - 1];
}

template<class T>
inline const T& NthArrayMember( const T & (array[]),size_t i)
{
return array[i - 1];
}


G++: declaration of `array' as array of references


I've tried about five different parenthesis combinations, but I just can't
get a reference to an array!

It's to be used as so:

int main()
{
int blah[50];

NthArrayMember(blah,45) = 56; //45th member = 56

extern void SomeFunc(int);

SomeFunc( NthArrayMember(blah,34) ); //Passes 34th member

}

Given that an array is not a type in the first place, I don't see how you
can create a reference to it. You can't even create a pointer to an array
(just a pointer to its first element). And, if the intent is to use it as
described, why not just:

blah[45] = 56;
SomeFunc(blah[34]);

?

-Howard
 
J

JKop

Howard posted:
why not just:

blah[45] = 56;
SomeFunc(blah[34]);

?

The sets the 46th member
That passes the 35th member.

Obviously I could write:

SomeFunc(blah[33]);

But I'm writing a pretty lengthly function and the computer and I think
differently: I associate the first member with 1, while the computer
associates it with 0. I'm bound to slip-up somewhere!

Anyway, here's the latest version:


template<class T, class R>
inline T& NthArrayMember( T (&array)[],R i)
{
return array[--i];
}

template<class T, class R>
inline const T& NthArrayMember( const T (& array)[],R i)
{
return array[--i];
}


g++ tester.cpp -ansi -pedantic -Wall -o t.exe

tester.cpp:83: parameter `array' includes reference to array of unknown
bound `
T[]'
tester.cpp:89: parameter `array' includes reference to array of unknown
bound `
const T[]'
tester.cpp: In function `int main()':
tester.cpp:99: `GetNthArrayMember' undeclared (first use this function)
tester.cpp:99: (Each undeclared identifier is reported only once for each
function it appears in.)


Any ideas?


-JKop
 
V

Victor Bazarov

JKop said:
[...]
template<class T, class R>
inline const T& NthArrayMember( const T (& array)[],R i)
{
return array[--i];
}

template<class T, int size, class R>
inline T& NthArrayMember(T (&array)[size], R i)
...

V
 
J

JKop

Okay, I've finally got it:


template<class T, class R>
inline T& NthArrayMember( T * const p_first_array_member,R i)
{
return p_first_array_member[--i];
}

template<class T, class R>
inline const T& NthArrayMember( const T * const p_first_array_member,R i)
{
return p_first_array_member[--i];
}


int main()
{
char blah[786];

extern void SomeFunc(char);

NthArrayMember(blah,56) = 72;

SomeFunc(NthArrayMember(blah,56));
}

void SomeFunc(char) { }



-JKop
 
J

JKop

Victor Bazarov posted:

template<class T, int size, class R>
inline T& NthArrayMember(T (&array)[size], R i)
...

V

I realized that finally but then decided that a pointer was
the way to go.

Thanks for the input.

-JKop
 
A

Ali Cehreli

Given that an array is not a type in the first place,

An array of a specific size is a type.
I don't see how
you can create a reference to it. You can't even create a pointer to an
array (just a pointer to its first element).

These are incorrect. You can have references and pointers to arrays
as well (not only to their first elements). The following program
demonstrates this:

#include <iostream>

size_t const arraySize = 10;

typedef int Array[arraySize];

// Function taking reference-to-array
void fill(Array & array, int value)
{
for (size_t i = 0; i != arraySize; ++i)
{
array = value;
}
}

// Function taking const-reference-to-array
void printMiddle(Array const & array)
{
std::cout << array[arraySize / 2] << '\n';
}

int main()
{
Array one = { 0 };
fill(one, 1);
Array two = { 0 };
fill(two, 2);

// Pointer to array (not to the first element!)
Array * p = 0;

p = &one;

// Dereferencing pointer-to-array
printMiddle(*p);

p = &two;
printMiddle(*p);
}

Ali
 
H

Howard

JKop said:
Howard posted:
why not just:

blah[45] = 56;
SomeFunc(blah[34]);

?

The sets the 46th member
That passes the 35th member.

Obviously I could write:

SomeFunc(blah[33]);

But I'm writing a pretty lengthly function and the computer and I think
differently: I associate the first member with 1, while the computer
associates it with 0. I'm bound to slip-up somewhere!

Wow! That's pretty basic stuff. If you're using constants, why not declare
some constants and use those instead of integer literals as the array
locations?
Anyway, here's the latest version:


template<class T, class R>
inline T& NthArrayMember( T (&array)[],R i)
{
return array[--i];
}

template<class T, class R>
inline const T& NthArrayMember( const T (& array)[],R i)
{
return array[--i];
}


g++ tester.cpp -ansi -pedantic -Wall -o t.exe

tester.cpp:83: parameter `array' includes reference to array of unknown
bound `
T[]'
tester.cpp:89: parameter `array' includes reference to array of unknown
bound `
const T[]'
tester.cpp: In function `int main()':
tester.cpp:99: `GetNthArrayMember' undeclared (first use this function)
tester.cpp:99: (Each undeclared identifier is reported only once for each
function it appears in.)


Any ideas?

Yep. Since an array always decays to a pointer when passed as a parameter,
why not just use a pointer (T*) instead? You can still index it just like
you've shown.

(And why the use of class R for the index? Do you foresee using some other
kind of index?)
 
J

JKop

Howard posted:
Wow! That's pretty basic stuff. If you're using constants, why not
declare some constants and use those instead of integer literals as the
array locations?

I have an array of digits:

wchar_t digits[] = L"1234567890";

To get 9:

NthArrayMember(digits, 9);

Now isn't that much more beautiful than specifying 8 when
you want 9! Again I must stress that this is a very
lengthly function!

(And don't suggest "0123456789"! ;-) )

(And why the use of class R for the index? Do you foresee using some
other kind of index?)

You never know, it's possible to do

class SomeClass
{
operator[](SomeCrazyClass& blah);
}


There's no overhead in allowing for that, so I may aswell!


-JKop
 
H

Howard

Ali Cehreli said:
Given that an array is not a type in the first place,

An array of a specific size is a type.
I don't see how
you can create a reference to it. You can't even create a pointer to an
array (just a pointer to its first element).

These are incorrect. You can have references and pointers to arrays
as well (not only to their first elements). The following program
demonstrates this:

#include <iostream>

size_t const arraySize = 10;

typedef int Array[arraySize];

// Function taking reference-to-array
void fill(Array & array, int value)
{
for (size_t i = 0; i != arraySize; ++i)
{
array = value;
}
}

// Function taking const-reference-to-array
void printMiddle(Array const & array)
{
std::cout << array[arraySize / 2] << '\n';
}

int main()
{
Array one = { 0 };
fill(one, 1);
Array two = { 0 };
fill(two, 2);

// Pointer to array (not to the first element!)
Array * p = 0;

p = &one;

// Dereferencing pointer-to-array
printMiddle(*p);

p = &two;
printMiddle(*p);
}

Ali


Well, now you've *created* a type (Array), which *can* be pointed to or
referenced. And the only reason you can do it at all is because you use a
compile-time constant to declare the array as a fixed size. That allows the
compiler to know how much memory the new type requires. This won't work for
a variable-length array passed as a parameter, because there is no type, and
you can't declare it as a type (because it's variable-length). (So, maybe I
should have specified that more clearly originally, but I thought it was
obvious in the context of the conversation my post was in.)

-Howard
 
J

JKop

I'd love to stay and chat, but it's 11:50pm here in Ireland
and I'm off to bed. Good night! (Well maybe some crap TV
first!)


-JKop
 
H

Howard

JKop said:
Howard posted:
Wow! That's pretty basic stuff. If you're using constants, why not
declare some constants and use those instead of integer literals as the
array locations?

I have an array of digits:

wchar_t digits[] = L"1234567890";

To get 9:

NthArrayMember(digits, 9);

Now isn't that much more beautiful than specifying 8 when
you want 9! Again I must stress that this is a very
lengthly function!

(And don't suggest "0123456789"! ;-) )

Damn! You beat me to it! :)

-Howard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top