473,544 Members | 1,974 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Two Dimensional Array Template

http://groups.google.com/group/comp....092f0f6c9bf13a

I think that the operator[]() member function does not work correctly, does
anyone else know how to make a template for making two dimensional arrays from
std::vectors ??? I want to use normal Array[ROW][COL] Syntax.
Jan 1 '07
272 13888

Gianni Mariani wrote:
Daniel T. wrote:
Gianni Mariani <gi*******@mari ani.wswrote:
Also, to placate Daniel T, I would specialize Array2D<boollik e so:

template <>
class Array2D<bool>;

... and then fill in the blanks whenever you need Array2D<bool>, if ever.
Can that be done? The code posted assumes that any portion of the vector
can be converted into an array of pointers. How would you change the
implementation when that is not the case?

Apart from vector<bool>, this IS the C++ standard for std::vector. As
for Array2D<T>, I suppose you can return a proxy that gens a
std::vector<T>: :reference_type instead of a pointer and there would be
no need to specialize Array2D. Still, if you don't need a <bool>
implementation, let's not make the OP worry about it.
Frankly I don't think vector<boolshou ld exist, at least not any
differently than any other type of vector. It throws a wrench into the
whole works and makes it impossible to create a real vector<bool>.

Jan 2 '07 #41
Gianni Mariani <gi*******@mari ani.wswrote:
I can show an implementation of [][] that calls call your (,) and most
compilers will optimize it so there is nothing different between calling
(,) or [][].
By all means, do so. Really, I'm interested in seeing it. If you can
show one that still uses the interface shown by Peter, I'll be very
surprised.
The FAQ is guilty of being a proponent of inventing a new syntax where
none in needed IMHO.

Now, if I create a bunch o 2D array templates, they will work fine with
both the new Array2D or a native 2D array. Do that with the (,) syntax!
I don't believe there is a "native 2D array" in C++, if there is, please
reference where in the standard it is specified.

Regardless, if you can show an interface that can work for "native 2D
arrays", row-major, column-major and sparse arrays, then you will have
taught me something very cool. I'd love to see it.
Jan 2 '07 #42

Gianni Mariani wrote:
>
Now, if I create a bunch o 2D array templates, they will work fine with
both the new Array2D or a native 2D array. Do that with the (,) syntax!
That is the only strength it has over () while suffering deficiencies
already iterated many times in this group and in the FAQ. _If_
backwards compatibility is the single most important issue you face
then it is probably appropriate to mimic a compatible interface.
Otherwise I think the other issues far outweigh this one, narrow
requirement.
>

It's just easier all the way around.
Only given a very specific set of needs...not "all the way around."

Jan 2 '07 #43
Noah Roberts wrote:
....
>
Frankly I don't think vector<boolshou ld exist, at least not any
differently than any other type of vector. It throws a wrench into the
whole works and makes it impossible to create a real vector<bool>.
I agree - but that is what the standard is.
Jan 2 '07 #44

Daniel T. wrote:
Regardless, if you can show an interface that can work for "native 2D
arrays", row-major, column-major and sparse arrays, then you will have
taught me something very cool. I'd love to see it.
Simply returning a "row_refere nce" from operator[] that itself has an
operator[] will allow you to do these things. It's just a might bit
more complex than the alternative and thus is a less optimal solution
unless truely needed.

class col_mjr_mtx
{
...
reference_type ref(int x, int y);
row_reference operator[](int x) { return rowref<col_mjr_ mtx>(this, x);
}
};

template < typename T >
class rowref
{
T * mtx;
int row;

public:
...
typename T::reference_ty pe operator[](int y) { return mtx->ref(row,
y); }
};

See, no big deal but is most easily implemented in terms of a function
or functor op call.

Jan 2 '07 #45
Daniel T. wrote:
Gianni Mariani <gi*******@mari ani.wswrote:
....
I don't believe there is a "native 2D array" in C++, if there is, please
reference where in the standard it is specified.
Here:
T x[2][2];
>
Regardless, if you can show an interface that can work for "native 2D
arrays", row-major, column-major and sparse arrays, then you will have
taught me something very cool. I'd love to see it.
<brain dump - be warned>

template <typename T>
class array2d
{
..... I'll let someone else fill in the blanks ...
..... const/non_const constructors etc ....

T & operator()( int, int );

deref_proxy operator[]( int i )
{
return deref_proxy( i, * this );
}

class deref_proxy
{
int i;
array2d & a;
inline deref_proxy( int ii, array2d & ia )
: i( ii ), a( ia )
{
}
public:
inline T & operator[]( int j )
{
return a(j,i);
}
};
};

In a micro-detail perspective, what the proxy does is collect the
arguments to the (,) call and calls it when it has all the info. Tests
I did a while back with popular compilers is that the assembly code
generated is identical. The proxy has no overhead whatsoever.

Hence, anything that can implemented with (,) I can also implement with
[][] with negligible if any performance issues. QED.


Jan 2 '07 #46
Gianni Mariani <gi*******@mari ani.wswrote:
Daniel T. wrote:
Gianni Mariani <gi*******@mari ani.wswrote:
...
I don't believe there is a "native 2D array" in C++, if there is, please
reference where in the standard it is specified.

Here:
T x[2][2];
How is that a reference in the standard? I don't believe the C++
standard defines multi-dimensional arrays at all. I may be wrong on this
point and if so, someone please correct me.
Regardless, if you can show an interface that can work for "native 2D
arrays", row-major, column-major and sparse arrays, then you will have
taught me something very cool. I'd love to see it.

<brain dump - be warned>
[snipped brain dump]

Now it is me who should have read the FAQ. :-) The procedure you
outlined is exactly what the FAQ recommends in item 13.12.

However, you have needlessly complicated your class simply to support a
particular syntax. It seems that for you, it *is* all about the syntax,
and you are willing to jump through a few hoops to support that syntax.
For me, if presented with a class like your array2d, I'll just call the
(,) directly rather than going through the proxy.

One last note, your array2d with proxy still doesn't support the
"native" 2d syntax... The below doesn't compile.

void foo( int b[] );

int main() {
array2d<inta( 10, 10 );
foo( a[3] );
}

So the reason you are supporting this particular syntax (so it will work
like "native" 2d arrays) doesn't fly.
Jan 3 '07 #47
Daniel T. wrote:
Gianni Mariani <gi*******@mari ani.wswrote:
Daniel T. wrote:
Gianni Mariani <gi*******@mari ani.wswrote:
...
I don't believe there is a "native 2D array" in C++, if there is, please
reference where in the standard it is specified.
Here:
T x[2][2];

How is that a reference in the standard? I don't believe the C++
standard defines multi-dimensional arrays at all. I may be wrong on this
point and if so, someone please correct me.
I don't you're making a distiction that has any relevant consequences.
Clearly multi-dimensional arrays have been implemented as arrays of
arrays for many years. Having a semantic argument about arrays of
arrays vs multi-dimensional arrays does not help your (,) argument.
The rule is that [][] is far more common than (,) for writing matrix
code.
>
Regardless, if you can show an interface that can work for "native 2D
arrays", row-major, column-major and sparse arrays, then you will have
taught me something very cool. I'd love to see it.
<brain dump - be warned>
[snipped brain dump]

Now it is me who should have read the FAQ. :-) The procedure you
outlined is exactly what the FAQ recommends in item 13.12.

However, you have needlessly complicated your class simply to support a
particular syntax. It seems that for you, it *is* all about the syntax,
and you are willing to jump through a few hoops to support that syntax.
For me, if presented with a class like your array2d, I'll just call the
(,) directly rather than going through the proxy.
Let's see if we disagree on any of these statements:

a) in C and in C++ matricies have been traditionally supported using
[][] (array of array) syntax. Hence there is a non-trivial body of
code and knowledge that is using [][] as opposed to (,).

b) Because of proxy classes, [][] is exactly equivalent in
functionality to (,) or perhaps even a superset. (BTW, I did confirm
again on gcc that the proxy class [][] creates exactly the same
instructions as (,). - I have attached the code example below).

c) Many standard matrix operations will be coded in templates
(multiples, inverses etc).

d) Many of these "matrix" templates can be used to operate on legacy C
and C++ code as well as newer code using proxy (or non proxy array
classes like the OP code) using [][].

Having shown what a proxy class might look like, you will see that all
the arguments in the FAQ (yes - all of them) supporting (,) have no
supportable rationale at all. Perhaps it's one of the most
short-sighted sections of the entire FAQ.

No generality at all is lost using [][] over (,) while the visa versa
statement is NOT true. (,) loses in 2 very significant ways.

1) new functions on older code
2) new learning curve for no real gain

I'll say it again, anying (,) can do [][] can do better.

You say "needlessly " complicated ? The complexity is in ONE place and
makes most other code easier to read. This is a Good(TM) tradeoff.
Needlessly changing a body of code using [][] to (,) is far more
complex. It's also not exactly a complex concept. Proxy classes are a
very easy concept to understand and code - after all it's only 20 lines
in this example.
One last note, your array2d with proxy still doesn't support the
"native" 2d syntax... The below doesn't compile.

void foo( int b[] );

int main() {
array2d<inta( 10, 10 );
foo( a[3] );
}

So the reason you are supporting this particular syntax (so it will work
like "native" 2d arrays) doesn't fly.
That would be easy to support using a conversion operator, however we
may or may not want to support that. That depends on the design goals
of the matrix class.

Regardless, if you really wanted to perform such operations, you can,
with constraints and contstaint violations can be compile time errors
that give you assurances that any code that does compile will do as
expected and any code that violates constraints never issues an
instruction.

------------The return of the proxy code---------

// on a FC5 machine using gcc, the instructions for the x() and y()
// functions emitted by the compiler are identical for
// optimization levels O1 and above on both IA32 and AMD64
// architectures.

template <typename T>
class array2d
{
public:

T & operator()( int, int );

class deref_proxy;

inline deref_proxy operator[]( int i )
{
return deref_proxy( i, * this );
}

class deref_proxy
{
const int i;
array2d & a;
public:
inline deref_proxy( const int ii, array2d & ia )
: i( ii ), a( ia )
{}
public:
inline T & operator[]( int j )
{
return a(i,j);
}
};

};
float y( array2d<float& a, int i, int j )
{
return a(i,j);
}

float x( array2d<float& a, int i, int j )
{
return a[i][j];
}

Jan 3 '07 #48
Noah Roberts wrote:
Gianni Mariani wrote:

Now, if I create a bunch o 2D array templates, they will work fine with
both the new Array2D or a native 2D array. Do that with the (,) syntax!

That is the only strength it has over () while suffering deficiencies
already iterated many times in this group and in the FAQ.
Not one of the arguments supporting the use of (,) only in the FAQ is
supportable with a coherent rationale.

As I have shown earlier in this thread, [][] and (,) are exactly the
same in funtionalitly and performance while [][] can also be a superset
if need be.
... _If_
backwards compatibility is the single most important issue you face
then it is probably appropriate to mimic a compatible interface.
Otherwise I think the other issues far outweigh this one, narrow
requirement.
That's where we disagree. There are no other issues IMHO.

Jan 3 '07 #49
Simon G Best wrote:
....
>
But let me ask you a question. If you use C-style subscripting, with
operator[], to access a whole row, then what do you use to access a
whole column?
Whatever you like !

a.Col(n)
a[COL+n]
a.Transpose()[n]
^a[n]
a++[n]

..... or don't provide one at all ...

Whatever tickles your fancy.

Jan 3 '07 #50

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
7652
by: ip4ram | last post by:
I used to work with C and have a set of libraries which allocate multi-dimensional arrays(2 and 3) with single malloc call. data_type **myarray = (data_type**)malloc(widht*height*sizeof(data_type)+ height* sizeof(data_type*)); //allocate individual addresses for row pointers. Now that I am moving to C++,am looking for something by...
60
10100
by: Peter Olcott | last post by:
I need to know how to get the solution mentioned below to work. The solution is from gbayles Jan 29 2001, 12:50 pm, link is provided below: > http://groups.google.com/group/comp.lang.c++/msg/db577c43260a5310?hl > >Another way is to create a one dimensional array and handle the >indexing yourself (index = row * row_size + col). This is...
6
3214
by: hyena | last post by:
Hi, I have a problem regarding passin 2 dimensional array into a function. I have a to pass into function f(), f is called many times and the size of a will change for each call. I am not interested in vector implementation in std library since speed is my major concern. the follwoing code does not work of couse, it show the idea what I...
4
559
by: Gernot Frisch | last post by:
Hi, I need a class, that has a 4 dimensional array (can be 3 dimensional, too) with such an operator: T operator()(int x1, int x2=0, int x3=0, int x4=0); that can be used as:
7
3881
by: nw | last post by:
Hi, We've been having a discussion at work and I'm wondering if anyone here would care to offer an opinion or alternative solution. Aparently in the C programming HPC community it is common to allocate multidimentional arrays like so: int *v_base = (int *) malloc(1000000*sizeof(int)); int **v = (int **) malloc(1000*sizeof(int *));
0
7424
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7365
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7607
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7772
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
5909
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5297
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
3415
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3409
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
661
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.