How to place variadic template arguments into an array? - c++

I want to have a variable number of arguments to a function and inside that function I want to place them into an array. I tried to use a fold expression for this because I didn't understand what they did. I thought they just simply expanded the arguments with a comma in between:
template <typename ... var_args_t>
void putArgumentsToArray(var_args_t&& ... values)
{
constexpr int num_args = sizeof ... (var_args_t);
int values_array[num_args] = {
(values, ...)
};
for (int i = 0; i < num_args; ++i)
std::cout << values_array[i] << "\n";
/* PRINTS [6, 0, 0, 0, 0, 0]*/
}
int main()
{
putArgumentsToArray(1, 2, 3, 4, 5, 6);
}
The end result is that the array is only initialised with one value(6), because all six arguments are evaluated as expressions, however the comma operator works so that only the last argument is returned. So the array has only one initialiser.
I know I can use a std::vector or a loop, but it would be really nice and clean if I could do this directly into the array initialiser.

You have confused the syntax a bit. You wished parentheses on other places
int values_array[num_args] = {
(values)...
};
or the same but without parentheses
int values_array[num_args] = {
values...
};
values... expands to
1, 2, 3, 4, 5, 6
Whereas (values, ...) expands to the comma operator in the parentheses
(1, 2, 3, 4, 5, 6)
that returns the single 6, the value of the last operand of the comma operator.

Related

Why does std:sqrt on Eigen's diagonal().row() fail with "no instance of overloaded function matches argument list"

I am trying to calculate the square root of each element of the .diagonal() of a Eigen::Matrix3d. Using
std::sqrt(matrix.diagonal().row(i))
will give me a compile error:
no instance of overloaded function "std::sqrt" matches the argument
list -- argument types are:
(Eigen::Block<Eigen::Diagonal<Eigen::Matrix<double, 3, 3, 0, 3, 3>,
0>, 1, 1, false>)C/C++(304)
I am using .row() in a for-loop to access each row of the diagonal vector.
Each element of the .diagonal() vector should be type double.
I am using a pointer dereference - but when I just print the .row() it works.
I guess the problem is within sqrt and the returned value from .row(). What am I doing wrong?
EDIT: .diagonal().array().sqrt() does the trick.
It's because the result type of matrix.diagonal().row(n) is a one by one matrix. You can convert this to a flat type with the .value() member function:
#include <iostream>
#include <Eigen/Dense>
int main()
{
Eigen::Matrix3f m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
std::cout << std::sqrt( m.diagonal().row(1).value() ) << "\n";
return 0;
}

How can I check equivalency between two arrays in C++?

So I have two arrays and I need to find a way to find the equivalency between two different arrays in C++. This is the function I made:
bool equivalent(int a[], int b[], int n)
for (int i=0; i < n; i++){
if (b[(i + 2) % 5] == a[i])
return true;
else return false;
}
}
and this is the array:
int main() {
cout << boolalpha;
int a1[5] = {1, 2, 3, 4, 5};
int a2[5] = {3, 4, 5, 1, 2};
cout << equivalent(a1, a2, 5) << endl;
I know my arthmetic is correct, because for example, a2[4], 4 plus 2 is 6, mod 5 is 1, and in the a1[0] position, there is a value of 2 which is the same as the a2[4] value. My only problem is, the resultant should be true, but because the for loop starts at 0, the whole function messes up, as the second arrays index would need to start at a different number for it to work. How would I go about solving this?
How would I go about solving this?
By using a debugger. Step through the program line by line. If the behaviour is different than it is supposed to, you've found the problem.
There are two problems with the program:
I know my arthmetic is correct, because for example, a2[4], 4 plus 2 is 6, mod 5 is 1, and in the a1[0] position, there is a value of 2 which is the same as the a2[4] value.
But you're comparing a1[0] with a2[2], not with a2[4]. You've got the order of the arguments reversed.
You only compare a1[0] and then return the result. In order to compare the entire array, you must not return until all elements have been checked (except the branch which returns false can return early).
I think easy way is to convert both array into string then compare both.

How do I make a C++ function implicitly convert a list of ints into a vector parameter?

I am working on a library whose functions commonly take a vector type (__v4si, or a vector of 4 signed ints) as a parameter. (Note that so far this has nothing to do with the C++ STL vectortemplate class; this is a more primitive construct used to let the compiler generate vectorized SIMD code.)
In my C code I customarily call a wrapper macro that takes a list of int arguments and initializes a __v4si like so:
#define MakeIndex(dims...) ((__v4si){ dims })
This of course works fine in C++ too, but I would like to take advantage of C++'s more expressive type system to clean up calls to my libraries APIs. For example, where I now write something like:
long idx = IndexDotProduct(MakeIndex(1, 2, 3), MakeIndex(4, 5, 6, 7));
which macro-expands to:
long idx = IndexDotProduct(((__v4si){1, 2, 3}), ((__v4si){4, 5, 6, 7}));
I would like instead to be able to write something along the lines of:
long idx = IndexDotProduct({1, 2, 3}, {4, 5, 6, 7});
So, essentially (I think) I want to define a class that is just syntactic sugar around the primitive __v4si type, but that has an implicit cast operator for the list initializer.
How do I do that in C++ 11?
Solution
Here is a formulation that works for both C and C++ code (now using more verbose names as copied and pasted from my library header files):
typedef struct vMAT_Index {
__v4si v;
#ifdef __cplusplus
vMAT_Index(__v4si v) : v(v) { }
vMAT_Index(int v0 = 0, int v1 = 0, int v2 = 0, int v3 = 0) : v((__v4si){ v0, v1, v2, v3 }) { }
#endif
} vMAT_Index;
#define vMAT_MakeIndex(dims...) ((vMAT_Index){ .v = { dims } })
static inline long
vMAT_Index_dot(vMAT_Index a,
vMAT_Index b)
{
__v4si c = a.v * b.v;
return (long)c[0] + c[1] + c[2] + c[3];
}
In C code you still use the helper macro like this:
long idx = vMAT_Index_dot(vMAT_MakeIndex(1, 2, 3), vMAT_MakeIndex(4, 5, 6, 7));
But now in C++ you can just write:
long idx = vMAT_Index_dot({ 1, 2, 3 }, { 4, 5, 6, 7 });
Thanks to nosid for providing the essential answer!
Use implicit constructors to automatically create a vector object from a brace-initializer list:
struct vector
{
vector(__v4si v);
vector(int i0, int i1, int i2, int i3);
};
long IndexDotProduct(vector lhs, vector rhs);
long idx = IndexDotProduct(((__v4si){ 1, 2, 3 }), { 4, 5, 6, 7 });

C++ casting static two-dimensional double array to double**

I have such matrix in my program:
double m[3][4] =
{
{2, 4, 5, 7},
{4, 5, 1, 12},
{9, 12, 13, -4}
};
And I'd like to cast it to double** type.
I've already tried simple double** a = (double**)m;, but it doesn't work (when I try to read any value, I get "Access violation reading location 0x00000000.", which means I'm trying to read from NULL adress.
I found almost working solution:
double *b = &m[0][0];
double **c = &b;
It works when I read field c[0][any]
But same NULL adress reading problem occurs, when I try to read value from field c[1][0].
What is the proper way to cast my double m[3][4] array to type double**?
edit:
You say that's impossible. So I'll change a problem a little bit. How can I pass two-dimensional double array as a parameter to a function? My function has prototype:
void calculate(double **matrix, int n); //where matrix size is always n by n+1
And it's working fine with dynamically-allocated arrays. I doubt that only way to make it work is allocating new dynamical array and copy original static array one element by another...
You can't.
The notation double** refers to an array of pointers. You don't have an array of pointers, you have an array of arrays of doubles.
You can't just cast the array. You are going to have to create something like this:
double m[3][4] =
{
{2, 4, 5, 7},
{4, 5, 1, 12},
{9, 12, 13, -4}
};
double *marray[3] = {m[0],m[1],m[2]};
calculate(marray,3);
Or you can use a loop:
const size_t n = 3;
double *marray[n];
for (size_t i=0; i!=n; ++i) {
marray[i] = m[i];
}
calculate(marray,n);
When you write
double m[3][4]
{
{2, 4, 5, 7},
{4, 5, 1, 12},
{9, 12, 13, -4}
};
The compiler actually creates an array of doubles as if you had written
double _m[] = {2, 4, 5, 7, 4, 5, 1, 12, 9, 12, 13, -4};
However, thanks to C/C++ type system, the compiler remembers that m's type
is double [3][4]. In particular it remembers the sizes 3 and 4.
When you write
m[i][j]
the compiler replaces it by
_m[i * 4 + j];
(The 4 comes from the second size in double [3][4].) For instance,
m[1][2] == 1 and _m[1 * 4 + 2] == _m[6] == 1 as well.
As others said, a double** is a different type which doesn't carry the
sizes with it. To consider double** a as a 3 x 4 matrix, a[0], a[1] and
a[2] must be pointers to double (that is, double*) pointing to the
first element of the corresponding row. You can achieve this with
double* rows[] = { &m[0][0], &m[1][0], &m[2][0] };
double** a = &rows[0];
A simple cast doesn't create the variable rows above. Let me present other
alternative (but equivalent) ways to define rows
double* rows[] = { &m[0][0], &m[0][0] + 4, &m[0][0] + 2 * 4};
double* rows[] = { &_m[0], &_m[4], &_m[2 * 4]};
As you can see, only the second size (i.e. 4) is necessary. In general, for
multi-dimensional arrays, all sizes but the first are required. For this
reason a 1-dimensional array
double x[4] = { 1, 2, 3, 4 };
can be implicitly converted to a double*
double* y = x;
Using this fact we can also write
double* rows[] = { _m, _m + 4, _m + 2 * 4};
Indeed, _m is converted to a double* pointing to m[0]. Then, in _m + 4,
_m is is converted to a double* pointing to m[0] and to this pointer
it's added 4. Hence, _m + 4 is a pointer the fourth double following
_m[0], which is _m[4] and so on.
So far I have explained why you cannot cast a double [3][4] (or any other sizes) to a double**. Now, I'shall show, in your particular case, how calculate can be defined.
template <int N>
void calculate(double (&m)[N][N+1]) {
// use m as a double[N][N+1]
}
You call
calculate(m);
and the compiler will deduce the size N for you. In general (i.e, when the second dimension is not the N + 1) you can write
template <int N, int M>
void calculate(double (&m)[N][M]) {
// use m as a double[N][M]
}
If you're always using arrays (no pointers) for initialization, and you are able to avoid the pointer stuff in your calculate function, you might consider the following option, which uses size deduction by templates.
template<int m, int n>
void doubleFunc(double (&mat)[m][n])
{
for (auto i = 0; i < m; i++)
{
for (auto j = 0; j < n; j++)
{
std::cout << mat[i][j] << std::endl;
}
}
}
It worked during my quick test.
double m[3][4] =
{
{2, 4, 5, 7},
{4, 5, 1, 12},
{9, 12, 13, -4}
};
doubleFunc(m);
You can pass a 2d array as a function parameter:
void calculate(double matrix[][y], int n);
Until variable-length arrays are in the C++ standard, your choices include:
If your compiler supports variable-length arrays as an extension, you can likely pass them with a function declaration such as void foo(std::size_t n, double a[][n+1]). Note that the compiler likely requires n to be passed before a parameter declaration that uses n or requires some special syntax.
You can pass a double * and do index arithmetic manually in the function: void foo(std::size_t n, double *a) { … a[row*(n+1) + column] … }
You can create a class the implements variable-length arrays by doing the index arithmetic in its accessor functions.
You can allocate space for n pointers to double, fill those pointers with pointers to each row of the array, and pass the address of the space.

What is the meaning of new int[25,2]?

What is the meaning of using the second parameter with a comma in the below code?
int *num = new int[25,2];
That's the comma operator in action: it evaluates it's operand and returns the last one, in your case 2.
So that is equivalent with:
int *num = new int[2];
It's probably safe to say that the 25,2 part was not what was intended, unless it's a trick question.
Edit: thank you Didier Trosset.
That's the comma operator in action: it evaluates it's operand and returns the last one, in your case 2. So that is equivalent with:
int *num = new int[2];
You are using the comma operator, which is making the code do something that you might not expect at a first glance.
The comma operator evaluates the LHS operand then evaluates and returns the RHS operand. So in the case of 25, 2 it will evaluate 25 (doing nothing) then evaluate and return 2, so that line of code is equivalent to:
int *num = new int[2];
// Declare a single-dimensional array
int[] array1 = new int[5];
// Declare and set array element values
int[] array2 = new int[] { 1, 3, 5, 7, 9 };
// Alternative syntax
int[] array3 = { 1, 2, 3, 4, 5, 6 };
// Declare a two dimensional array
int[,] multiDimensionalArray1 = new int[2, 3];
// Declare and set array element values
int[,] multiDimensionalArray2 = { { 1, 2, 3 }, { 4, 5, 6 } };
// Declare a array
int[][] Array = new int[6][];
// Set the values of the first array in the array structure
Array[0] = new int[4] { 1, 2, 3, 4 };