Mysterious oneliner template code, any one? [duplicate] - c++

This question already has answers here:
Can someone explain this template code that gives me the size of an array? [duplicate]
(4 answers)
Closed 7 years ago.
I was reading this page :
C++ Tip: How To Get Array Length. The writer presented a piece of code to know the size of static arrays.
template<typename T, int size>
int GetArrLength(T(&)[size]){return size;} // what does '(&)' mean ?
.
.
.
int arr[17];
int arrSize = GetArrLength(arr); // arrSize = 17
Could anyone please shed the light on this code, because I couldn't understand how it really works.

The function is passed a reference (&) to an array of type T, and size size.

sizeof(x)/sizeof(x[0])
Won't catch errors if the array degrads to a pointer type, but it will still compile!
Templated version is bullet proof.

T(&)[size] is reference to T[size]. If you don't use reference C++ will treat T[size] as T*, and function template parameter deduction would not work.

Wow, that's tricky. I don't know either, but if you keep reading down into the comments on that page:
is essentially
int arr[17]; int arrSize =
GetArrLength(arr);
which creates this function:
int GetArrLength(int(&)[17]){return
17;}
So & must mean reference like it always does, so it's taking a reference of the array type and the size (second item in the template) is then the size of the incoming array.
Think I'll stick with old
sizeof(x)/sizeof(x[0])

Related

Passing multidimensional array to a function using a variable as a parameter [duplicate]

This question already has answers here:
How do I pass a reference to a two-dimensional array to a function?
(5 answers)
Closed 7 years ago.
Sorry if this is really easy to fix or a stupid question but I've only recently started programming.
So basicly in void main() I've declared a 2D array like so:
void main()
{
const int grid = 5;
array[grid][grid];
{
However I would like to pass this into a function like this:
void drawGrid(int grid, bool array[][])
{
}
This creates an error as the second parameter needs to have a number. But that's a problem since in main I declared my array using a variable.
void drawGrid(int grid, bool array[grid][grid])
{
}
Putting variables in the parameters does not work.
How do I go about passing the array to this function whilst using the int variable grid inside the parameters.
I have searched a lot and looked at answers from people who had similar problems to me but I just could not seem to figure out what to do specifically. Could anyone please show me how to fix the problem, I'd be incredibly greatful as I've been trying to work this out for almost two hours now. Thanks.
You can use a function template with the size as the template parameter.
template <size_t grid>
void drawGrid(bool array[][grid])
{
}
and call it simply with:
drawGrid(array);
or
drawGrid<grid>(array);

C++ Returning an Array and Assigning It to a Variable [duplicate]

This question already has answers here:
How do I use arrays in C++?
(5 answers)
Closed 8 years ago.
So I have a homework problem that asks that I write a function that takes an array of chars, a char, and an int pointer. The function should loop through the array of chars, ignore any instance of the second parameter char, and create a new array which is composed of the characters in the original array other than instances of the second parameter char. Then the original length parameter needs to be changed to the new length, and the new array should be returned. I'm very new to C++ so pointers are a new concept which I haven't fully grasped yet.
char *Problem5(char chars[], char letter, int *length){
int newLength=0;
int counter=0;
for(int i=0;i<*length;i++){
if(chars[i]!=letter){
newLength++;
}
}
char newChars[newLength];
for(int x=0;x<*length;x++){
if(chars[x]!=letter){
newChars[counter]=chars[x];
counter++;
}
}
*length=newLength;
return newChars;
}
There is my function, I know the algorithm works fine but it won't compile.
char chars2[10] = {'g','g','c','g','a','g','g','g','t','g'};
printArray(chars2,10);
char *arrayPointer;
arrayPointer = Problem5(chars2,'g',length1);
printArray(arrayPointer,3);
And this is the section of my main function where it is called. I need to print out the resultant array, and so I try to assign it to a pointer, but this line:
arrayPointer = Problem5(chars2,'g',length1);
Throws an error: Invalid conversion from 'char' to 'char*' A little insight would be very much appreciated because I have no clue what I'm doing wrong.
Your algorithm looks ok and your code looks pretty much all right. I am a little skeptical of this line :
char newChars[newLength];
because you can't allocate an array at compile time with a variable size. Is it possible that the code you posted isn't exactly the code you tried to compile?
Change the line above to
char *newChars = new char[newLength];
and the array will be allocated dynamically at run time. I cannot understand why you would get an "Invalid conversion from 'char' to 'char*'" error compiling
arrayPointer = Problem5(chars2,'g',length1);
given the definitions that you've provided. The only things that have type "char*" are the first parameter to and return value from Problem5, and those look to be the correct types from what you've posted.

Array Size Declaration issue [duplicate]

This question already has answers here:
Why aren't variable-length arrays part of the C++ standard?
(10 answers)
Closed 8 years ago.
int n=5;
int arr[n];
I want to declare size of array as above in C++, but I get error while compiling. I find a lot of code in internet which uses these type of declaration instead of simple putting int arr[5]. How come the code compiles successfully for them but not for me. P.S: I use windows7 and Visual Studio(IDE).
Error Message : Expresion must have a constant value
The number of elements of the array, the array bound, must be a constant expression.
You have to use
const int n = 5;
or
constexpr int n = 5;
else it is a non standard extension : variable length array (VLA).
The error message actually describes rather well what’s going on: C++ does not support arrays with a non-constant size (more precisely, the size needs to be known at compile time).
There are two solutions for this:
If the size is actually a constant, declare it as constexpr (if you can’t use C++11, you can also use const):
constexpr int n = 5;
std::array<int, n> arr;
Which requires the standard header <array>. Or, if you cannot use C++11, change the second line to
int arr[n];
If the size isn’t known at compile time, don’t use a static array, use a dynamic container instead:
int n = 5;
std::vector<int> arr(n);
This requires the <vector> standard header.

Why in C++ sizeof(array[]) behave in different way for bool array? [duplicate]

This question already has answers here:
When a function has a specific-size array parameter, why is it replaced with a pointer?
(3 answers)
Closed 9 years ago.
Why in C++ sizeof(array) behave in different way for bool array then for arrays containing other types of data ?
Edition :
I'm asking because
sizeof(boolarray)/sizeof(boolarray[0])
don't give size of boolarray.
but this simple code prints :
4
1
////////////////////////////
#include<iostream>
using namespace std;
void printBoolArray(bool* boolarray){
cout<<sizeof(boolarray)<<"\n";
cout<<sizeof(boolarray[0]);
}
int main(){
bool boolarray[10]={false};
printBoolArray(boolarray);
}
know I understand sizeof in function which gives the size of object which makes reference, this is my 9 day with c++, sorry for stupid question, it's so obvious now
It doesn't act differently. What makes you think it does? Are you making incorrect assumptions about the size of a bool?
As has been alluded to in the comments, if you are passing an array to a function and attempting to calculate its size there, that doesn't work. You can't pass arrays to (or return them from) functions. For example:
void foo(int array[10])
{
auto size = sizeof(array);
// size == sizeof(int*), you didn't pass an array
}
#include <cstddef>
#include <iostream>
template<std::size_t n>
void printBoolArray(bool (&boolarray)[n]){
std::cout<<sizeof(boolarray)<<"\n";
std::cout<<sizeof(boolarray[0]);
}
int main(){
bool boolarray[10]={false};
printBoolArray(boolarray);
}
The above works.
sizeof(bool*) is the size of the pointer, not the array it points to.
Above, I carefully maintained the type of the boolarray. As it happens, this technique also extracts the size into the compile-time constant n.
This doesn't scale well, because when you pass arrays to functions, they rapidly decay to pointers. This is one of the reasons why std::array or std::vector can be advised -- they have fewer quirks than C style arrays.
As others have explained, arrays degenerate to pointers when passed to a function.
However, there is one work around; you can use templates.
template<typename T, size_t N>
size_t length(T (&)[N]) {
return N;
}

In a function declaration, what does passing a fixed size array signify? [duplicate]

This question already has answers here:
Why can one specify the size of an array in a function parameter?
(3 answers)
Closed 3 years ago.
This feels like a really stupid thing to ask, but I had someone taking a programming class ask me for some help on an assignment and I see this in their code (no comments on the Hungarian notation please):
void read_dictionary( string ar_dictionary[25], int & dictionary_size ) {...
Which, as mainly a C# programmer (I learned about C and C++ in college) I didn't even know you could do. I was always told, and have read since that you're supposed to have
void read_dictionary( string ar_dictionary[], int ar_dictionary_size, int & dictionary_size ) {...
I'm told that the professor gave them this and that it works, so what does declaring a fixed size array like that even mean? C++ has no native way of knowing the size of an array being passed to it (even if I think that might've been changed in the newest spec)
In a one dimensional array It has no significance and is ignored by the compiler. In a two or more dimensional array It can be useful and is used by the function as a way to determine the row length of the matrix(or multi dimensional array). for example :
int 2dArr(int arr[][10]){
return arr[1][2];
}
this function would know the address of arr[1][2] according to the specified length, and also the compiler should not accept different sizes of arrays for this function -
int arr[30][30];
2dArr(arr);
is not allowed and would be a compiler error(g++) :
error: cannot convert int (*)[30] to int (*)[10]
The 25 in the parameter declaration is ignored by the compiler. It's the same as if you'd written string ar_dictionary[]. This is because a parameter declaration of array type is implicitly adjusted to a pointer to the element's type.
So the following three function declarations are equivalent:
void read_dictionary(string ar_dictionary[25], int& dictionary_size)
void read_dictionary(string ar_dictionary[], int& dictionary_size)
void read_dictionary(string *ar_dictionary, int& dictionary_size)
Even in the case of the first function, with the size of the array explicitly declared, sizeof(ar_dictionary) will return the same value as sizeof(void*).
See this sample on Codepad:
#include <string>
#include <iostream>
using namespace std;
void read_dictionary(string ar_dictionary[25], int& dictionary_size)
{
cout << sizeof(ar_dictionary) << endl;
cout << sizeof(void*) << endl;
}
int main()
{
string test[25];
int dictionary_size = 25;
read_dictionary(test, dictionary_size);
return 0;
}
Output (the exact value is, of course, implementation-dependent; this is purely for example purposes):
4
4
I always though that passing fixed size C++ arrays was a "half baked" feature of C++. For example, ignored size matching or only being able to specify the first index size, etc... Until recently I learn this idiom:
template<size_t N1, size_t N2> // enable_if magic can be added as well
function(double(&m)[N1][N2]){
... do something with array m...knowing its size!
}
Reference: Can someone explain this template code that gives me the size of an array?