Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use decltype to declare the return type

I've got the following code snippet:

int odd[] = { 1,3,5,7,9 };
int even[] = { 0,2,4,6,8 };

// returns a pointer to an array of five int elements
decltype(odd) *arrPtr(int i) {
    return (i % 2) ? &odd : &even; // returns a pointer to the array
}

int main()
{
    int *res1 = arrPtr(3);
    decltype(odd) *res2 = arrPtr(3);
    auto res3 = arrPtr(3);
}

For the first line I get the following error message:

int (*arrPtr(int i))[5]

returns a pointer to an array of five int elements

Error: a value of type "int (*)[5]" cannot be used to initialize an entity of type "int *"

Why can't int* be used to initialize my return value from arrayPtr()? I would have assumed that the compiler is doing an explicit conversion.

Furthermore, what would one use as return type (best practice)?

like image 835
HansMusterWhatElse Avatar asked May 24 '26 08:05

HansMusterWhatElse


2 Answers

It seems odd is declared as an array of int:

int odd[5];

The type of odd is int[5] and taking the address (or adding a * to decltype(odd)) of this array yields an int(*)[5]. It seems, you actually want to use the decayed type of odd:

decltype(+odd) arrPtr(int i) {
    return i % 2? odd: even;
}

int main() {
   int*           res1 = arrPtr(3);
   decltype(+odd) res2 = arrPtr(3);
   auto           res3 = arrPtr(3)
}

Note this use of unary + which forces decay of the array to become a pointer to the first element of the array.

If you really mean to return a pointer to the array, you'd need to use a suitable type when capturing the result (assuming the original implementation):

int (*res1)[5]      = arrPtr(3);
decltype(odd)* res2 = arrPtr(3);
auto res3           = arrPtr(3);

Note, that this is a pointer to an array of 5 int, i.e., you'd access an element of it using

(*res1)[3];

or

res1[0][3];
like image 93
Dietmar Kühl Avatar answered May 26 '26 21:05

Dietmar Kühl


int (&)[5] can decay to int *, it is not the case for int (*)[5].

You may change your code to

decltype(odd)& arrPtr(int i) {
    return (i % 2) ? odd : even; // returns the reference to the array
}

and then

int main()
{
    int *res1 = arrPtr(3);
    decltype(odd)& res2 = arrPtr(3); // int (&)[5]
    auto res3 = arrPtr(3); // int*
    const auto& res4 = arrPtr(3); // const int (&)[5]
}
like image 21
Jarod42 Avatar answered May 26 '26 21:05

Jarod42



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!