I'm getting an error when using a C program that accepts **float as
arguments in my C++ code. Here the code (short):
float A[3][3] = {0,0,0,1,2,0,3,4,0};
float W[3] = {0,0,0};
float V[3][3] = {0,0,0,0,0,0,0,0,0};
svdcmp(A,2,2,W,V);
where the function svdcmp is void svdcmp(float **a, int m, int n, float
w[], float **v).
The compiler (MSVC++) message is:
Error C2664: 'svdcmp' : cannot convert parameter 1 from 'float [3][3]'
to 'float ** '. Types pointed to are unrelated; conversion requires
reinterpret_cast, C-style cast or function-style cast
I'm sure I'm making a blunder somewhere but it's so long since I've
used either C or C++...! Thanks for any help. 6 1914
<sp******@yahoo.com> wrote... I'm getting an error when using a C program that accepts **float as arguments in my C++ code. Here the code (short):
float A[3][3] = {0,0,0,1,2,0,3,4,0}; float W[3] = {0,0,0}; float V[3][3] = {0,0,0,0,0,0,0,0,0};
svdcmp(A,2,2,W,V);
where the function svdcmp is void svdcmp(float **a, int m, int n, float w[], float **v).
The compiler (MSVC++) message is: Error C2664: 'svdcmp' : cannot convert parameter 1 from 'float [3][3]' to 'float ** '. Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
I'm sure I'm making a blunder somewhere but it's so long since I've used either C or C++...! Thanks for any help.
A two-dimensional array of T (T [N][M]) is not convertible to a pointer
to a pointer to T. Period.
Do not do reinterpret_cast either because it won't work. The types do
_not_ have the same data layout in memory. The only thing that is kind
of similar is that you can use operator[] on both, and the resulting
type allows you to use operator[] again, and the result is T&. But the
main difference is that the former type yields 'array of T' when you
use operator[], and the latter yields 'a pointer to T'.
If you have control over how 'svdcmp' is written, and you want to keep
it working for both T** and T[][], make two templates out of it. One
will have T[N][M] as the argument type, the other will have T**.
If you don't have control over 'svdcmp', and you just have to convert
your arrays into a pointer to pointers, then you'll need to create some
temporary arrays of pointers and pass them:
float A[3][3] = { ...
float V[3][3] = { ...
float *pA[] = { &A[0][0], &A[1][0], &A[2][0] };
float *pV[] = { &V[0][0], &V[1][0], &V[2][0] };
svdcmp(pA,2,2,W,pV);
Now, without knowing more I can't vouch for the functionality being up
to your needs, but it should at least give you an idea.
V
<sp******@yahoo.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com... I'm getting an error when using a C program that accepts **float as arguments in my C++ code. Here the code (short):
float A[3][3] = {0,0,0,1,2,0,3,4,0}; float W[3] = {0,0,0}; float V[3][3] = {0,0,0,0,0,0,0,0,0};
svdcmp(A,2,2,W,V);
where the function svdcmp is void svdcmp(float **a, int m, int n, float w[], float **v).
The compiler (MSVC++) message is: Error C2664: 'svdcmp' : cannot convert parameter 1 from 'float [3][3]' to 'float ** '. Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
I'm sure I'm making a blunder somewhere but it's so long since I've used either C or C++...! Thanks for any help.
No, no no 2D array is not the same as a pointer to pointer - think of it
this way, an array is a contiguous set of data, so declaring float[3][3]
will occupy 3*3*sizeof(float) contigous bytes of memory. Pointers can point
*anywhere* and it is likely that they will if they were allocated at
different points in the program.
Allan
Victor Bazarov wrote: ... If you have control over how 'svdcmp' is written, and you want to
keep it working for both T** and T[][], make two templates out of it. One will have T[N][M] as the argument type, the other will have T**. ...
Ah, thanks for the tips. I do have the source code for svdcmp() - I'd
like to modify it to accept *a (much more convenient) rather than **a
or a[][]. Just a sanity check - in the code wherever it says a[j][k]
then I need to change this to a[j*N+k] (or a[k*N+j], whatever you know
what I mean :) where N is the length of that dimension.
you only need a single pointer, and then you can access it however u
like.
#define WIDTH 5
#define HEIGHT 5
#define ACCESS(ptr, x, y) (ptr[(y*WIDTH)+x])
float array[WIDTH][HEIGHT] = { .... };
float *parray = array;
ACCESS(parry, 1, 1); // same as array[1][1]
In message <7s********************@comcast.com>, Victor Bazarov
<v.********@comAcast.net> writes <sp******@yahoo.com> wrote... I'm getting an error when using a C program that accepts **float as arguments in my C++ code. Here the code (short):
float A[3][3] = {0,0,0,1,2,0,3,4,0}; float W[3] = {0,0,0}; float V[3][3] = {0,0,0,0,0,0,0,0,0};
svdcmp(A,2,2,W,V);
where the function svdcmp is void svdcmp(float **a, int m, int n, float w[], float **v).
The compiler (MSVC++) message is: Error C2664: 'svdcmp' : cannot convert parameter 1 from 'float [3][3]' to 'float ** '. Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
I'm sure I'm making a blunder somewhere but it's so long since I've used either C or C++...! Thanks for any help. A two-dimensional array of T (T [N][M]) is not convertible to a pointer to a pointer to T. Period.
Do not do reinterpret_cast either because it won't work. The types do _not_ have the same data layout in memory. The only thing that is kind of similar is that you can use operator[] on both, and the resulting type allows you to use operator[] again, and the result is T&. But the main difference is that the former type yields 'array of T' when you use operator[], and the latter yields 'a pointer to T'.
If you have control over how 'svdcmp' is written, and you want to keep it working for both T** and T[][], make two templates out of it. One will have T[N][M] as the argument type, the other will have T**.
Better still, define a template "matrix traits" class which encapsulates
the concept of Matrix and provides typedefs for things like value_type
and reference, and static functions for element access and size, and
specialise that for different argument types. Then template svdcmp on
generic Matrix types deduced from its arguments. Now you can add new
Matrix representations without having to make any changes to the code of
svdcmp.
// Untested code
template <class M>
struct MatrixTraits
{
/* assume that by default this will be instanced with M as some kind of
Matrix class which already provides all the needed functionality:
*/
typedef M matrix_type;
typedef typename M::value_type value_type;
typedef typename M::reference reference;
static reference element(matrix_type & m, size_t i, size_t j)
{ return m(i, j); }
static value_type element(matrix_type const & m, size_t i, size_t j)
{ return m(i, j); }
static size_t width(matrix_type & m) { return m.width(); }
static size_t height(matrix_type & m) { return m.height(); }
// etc...
};
// specialise for array of array
template <class T, size_t M, size_t N>
struct MatrixTraits <T[M][N]>
{
typedef T value_type;
typedef T & reference;
typedef T matrix_type[M][N];
static reference element(matrix_type & m, size_t i, size_t j)
{ return m[i][j]; }
static value_type element(matrix_type const & m, size_t i, size_t j)
{ return m[i][j]; }
static size_t width(matrix_type & m) { return M; }
static size_t height(matrix_type & m) { return N; }
// etc...
};
typedef typename M::value_type value_type;
static value_type element(M & m, size_T i, size_t j) { return m(i, j); }
static size_t width(M & m) { return m.width(); }
static size_t height(M & m) { return m.height(); }
// etc...
};
template <class A, class V, class W>
void svdcmp(A & a, V & v, W & w)
{
typedef MatrixTraits<A> at;
typedef MatrixTraits<V> vt;
typedef MatrixTraits<W> wt;
size_t const m = at::width(a);
size_t const n = at::height(a);
for (size_t i = 0; i<m; ++i)
for (size_t j = 0; i<n; ++i)
{
at::value_type a_ij = at::element(a, i, j);
/etc.../
}
}
Or something like that. If you don't have control over 'svdcmp', and you just have to convert your arrays into a pointer to pointers, then you'll need to create some temporary arrays of pointers and pass them:
float A[3][3] = { ... float V[3][3] = { ...
float *pA[] = { &A[0][0], &A[1][0], &A[2][0] }; float *pV[] = { &V[0][0], &V[1][0], &V[2][0] };
svdcmp(pA,2,2,W,pV);
Now, without knowing more I can't vouch for the functionality being up to your needs, but it should at least give you an idea.
V
--
Richard Herring
[reposted, less scrambled formatting :-( ]
In message <7s********************@comcast.com>, Victor Bazarov
<v.********@comAcast.net> writes <sp******@yahoo.com> wrote... I'm getting an error when using a C program that accepts **float as arguments in my C++ code. Here the code (short):
float A[3][3] = {0,0,0,1,2,0,3,4,0}; float W[3] = {0,0,0}; float V[3][3] = {0,0,0,0,0,0,0,0,0};
svdcmp(A,2,2,W,V);
where the function svdcmp is void svdcmp(float **a, int m, int n, float w[], float **v).
The compiler (MSVC++) message is: Error C2664: 'svdcmp' : cannot convert parameter 1 from 'float [3][3]' to 'float ** '. Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
I'm sure I'm making a blunder somewhere but it's so long since I've used either C or C++...! Thanks for any help. A two-dimensional array of T (T [N][M]) is not convertible to a pointer to a pointer to T. Period.
Do not do reinterpret_cast either because it won't work. The types do _not_ have the same data layout in memory. The only thing that is kind of similar is that you can use operator[] on both, and the resulting type allows you to use operator[] again, and the result is T&. But the main difference is that the former type yields 'array of T' when you use operator[], and the latter yields 'a pointer to T'.
If you have control over how 'svdcmp' is written, and you want to keep it working for both T** and T[][], make two templates out of it. One will have T[N][M] as the argument type, the other will have T**.
Better still, define a template "matrix traits" class which encapsulates
the concept of Matrix and provides typedefs for things like value_type
and reference, and static functions for element access and size, and
specialise that for different argument types. Then template svdcmp on
generic Matrix types deduced from its arguments. Now you can add new
Matrix representations without having to make any changes to the code of
svdcmp.
// Untested code
template <class M>
struct MatrixTraits
{
/* assume that by default this will be instanced with M as some kind of Matrix class
which already provides all the needed functionality:
*/
typedef M matrix_type;
typedef typename M::value_type value_type;
typedef typename M::reference reference;
static reference element(matrix_type & m, size_t i, size_t j)
{ return m(i, j); }
static value_type element(matrix_type const & m, size_t i, size_t j)
{ return m(i, j); }
static size_t width(matrix_type & m) { return m.width(); }
static size_t height(matrix_type & m) { return m.height(); }
// etc...
};
// specialise for array of array
template <class T, size_t M, size_t N>
struct MatrixTraits <T[M][N]>
{
typedef T value_type;
typedef T & reference;
typedef T matrix_type[M][N];
static reference element(matrix_type & m, size_t i, size_t j)
{ return m[i][j]; }
static value_type element(matrix_type const & m, size_t i, size_t j)
{ return m[i][j]; }
static size_t width(matrix_type & m) { return M; }
static size_t height(matrix_type & m) { return N; }
// etc...
};
template <class A, class V, class W>
void svdcmp(A & a, V & v, W & w)
{
typedef MatrixTraits<A> at;
typedef MatrixTraits<V> vt;
typedef MatrixTraits<W> wt;
size_t const m = at::width(a);
size_t const n = at::height(a);
for (size_t i = 0; i<m; ++i)
for (size_t j = 0; i<n; ++i)
{
at::value_type a_ij = at::element(a, i, j);
/etc.../
}
}
Or something like that.
If you don't have control over 'svdcmp', and you just have to convert your arrays into a pointer to pointers, then you'll need to create some temporary arrays of pointers and pass them:
float A[3][3] = { ... float V[3][3] = { ...
float *pA[] = { &A[0][0], &A[1][0], &A[2][0] }; float *pV[] = { &V[0][0], &V[1][0], &V[2][0] };
svdcmp(pA,2,2,W,pV);
Now, without knowing more I can't vouch for the functionality being up to your needs, but it should at least give you an idea.
V
--
Richard Herring This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: jr |
last post by:
Sorry for this very dumb question, but I've clearly got a long way to go!
Can someone please help me pass an array into a function. Here's a starting
point.
void TheMainFunc()
{
// Body of...
|
by: Bangalore |
last post by:
Hi all,
Plz clarify me, on the implementation of two or three dimensional
array using overloaded operator.
Thanks, in advance
Bangalore
|
by: Pavel Stehule |
last post by:
Hello,
Is possible merge two arrays like
array + array => array
select array_append(array, array);
ERROR: function array_append(integer, integer) does not exist
|
by: Joshua Neuheisel |
last post by:
The following code compiles with gcc 3.2.2 and Visual C++ 6:
#include <stdio.h>
int main()
{
int a = {3, 4};
printf ("%d\n", 0);
return 0;
}
|
by: prashna |
last post by:
Hi all,
I have seen a piece of code(while doing code review) which declared an
array of size 0.One of my friend told although it is not standard
C,some compilers will support this..I am very...
|
by: Kavya |
last post by:
int main (){
int a={{1,2,3},{4,5,6}};
int (*ptr)=a;
/* This should be fine and give 3 as output*/
printf("%d\n",(*ptr));
++ptr;
|
by: arnuld |
last post by:
int main()
{
const char* arr = {"bjarne", "stroustrup", "c++"};
char* parr = &arr;
}
this gives an error:
$ g++ test.cpp
test.cpp: In function 'int main()':
test.cpp:4: error: cannot...
|
by: =?Utf-8?B?U2hhcm9u?= |
last post by:
Hi Gurus,
I need to transfer a jagged array of byte by reference to unmanaged
function, The unmanaged code should changed the values of the array, and when
the unmanaged function returns I need...
|
by: mdh |
last post by:
>From p112 ( K&R).
Given an array declared as
static char arr= { { 0,1,........},{0,1,.....}};
let arr be passed as an argument to f.
f( int (*arr) ) {....}
It is noted that the...
|
by: pereges |
last post by:
I've an array :
{100,20, -45 -345, -2 120, 64, 99, 20, 15, 0, 1, 25}
I want to split it into two different arrays such that every number <=
50 goes into left array and every number 50 goes...
|
by: DolphinDB |
last post by:
Tired of spending countless mintues downsampling your data? Look no further!
In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: Vimpel783 |
last post by:
Hello!
Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
|
by: PapaRatzi |
last post by:
Hello,
I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
|
by: CloudSolutions |
last post by:
Introduction:
For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
|
by: af34tf |
last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
|
by: Faith0G |
last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...
| | |