1

Is there a way to pass default value to array which is passed by reference to a function so that passing it is not necessary?

I have a function like this:

void foo(int (&arr) [3])
{
    //some code...
}

Then i tried this:

void foo(int (&arr) [3] = nullptr)
{
    //some code...
}

but it obvoiusly didn't work because reference cannot be nullptr and it is not even an array.

EDIT: I would like not to use std::array if possible, and I also need to know the size of passed array without passing its size which is why I didn't do this: int (*arr)[3].

6
  • Probably simpler to write a separate overload of foo that doesn't take an argument. Commented Jun 18, 2023 at 15:13
  • 2
    Pass a pointer int (*arr)[3] = nullptr? Commented Jun 18, 2023 at 15:14
  • 1
    void foo() { int dummy[3]; foo(dummy); } Commented Jun 18, 2023 at 15:14
  • 1
    Reopened since the "duplicate" doesn't answer how to use a default argument, which is the whole point of this question. Commented Jun 18, 2023 at 15:42
  • 1
    Also consider void foo(const int (&arr)[3] = { 1, 2, 3 }) if you don't need to modify the array Commented Jun 18, 2023 at 19:31

2 Answers 2

3

In C++, you cannot directly pass a default value to an array passed by reference. However, you can achieve a similar effect by overloading the function with a version that accepts a default array and calls the original function with it.

Here is a Code

void foo(int (&arr)[3]){}

void foo()
{
    int defaultArr[3] = {1, 2, 3};
    foo(defaultArr);
}
int main()
{
    int arr[3] = {2, 1, 4};
    foo(arr); 

    foo();     
    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

3

I also need to know the size of passed array without passing its size which is why I didn't do this: int (*arr)[3].

This explanation doesn't make sense to me. The array size is encoded in the pointer type. Simply indirect through the pointer and you get a int (&arr) [3]. Example:

void foo(int (*arr)[3] = nullptr)
{
    if (arr)
        std::cout << std::size(*arr);
    else
        std::cout << "nullptr";
}

As such, using a pointer to array is an answer to your question.

Another option is to use an optional span:

void foo(std::optional<std::span<int, 3>> arr = std::nullopt)

While the parameter type is a bit more verbose, this allows you to pass an array directly without using the addressof operator. Furthermore, this allows passing other contiguous ranges too, not just arrays.


If you know at compile time that you want the default option, then I recommend using the overload solution in Syed's answer, but that won't work if the option is determined at runtime.

8 Comments

Ehh "The array size is encoded in the pointer type" - not really; you cannot get the size of an array from a pointer. You'd need a std::array or std::vector for that - with a .size() member you can call.
@JesperJuhl you cannot get the size of an array from a pointer. Yes, you can get the size from a pointer to array. You'd need a std::array or std::vector for that No, you don't need those.
please demonstrate getting the array size from just a pointer to the first element of an array . Prove me wrong.
@JeJo True, but then we have a template, which OP might need to avoid. But if template is not an issue, then it's good for generality indeed. The optional span version can be templated similarily.
@JeJo std::optional might require the caller side also to change/ use/ convert the arrays to optional type as well The conversion is implicit and trivial.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.