如何使在C++函数中将数组按引用传递变为可选?

huangapple go评论62阅读模式
英文:

How to make passing an array by reference optional in C++ function?

问题

有没有办法将默认值传递给通过引用传递给函数的数组,以便不必传递它?

我有一个这样的函数:

void foo(int (&arr)[3])
{
    //一些代码...
}

然后我尝试过这样:

void foo(int (&arr)[3] = nullptr)
{
    //一些代码...
}

但显然它不起作用,因为引用不能是 nullptr,而且它甚至不是一个数组。

编辑:
如果可能的话,我希望不使用 std::array,并且我还需要知道传递的数组的大小,而不必传递它的大小,这就是为什么我没有这样做的原因:int (*arr)[3]

英文:

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].

答案1

得分: 3

在C++中,你不能直接将默认值传递给通过引用传递的数组。然而,你可以通过重载函数的方式实现类似的效果,重载的版本接受一个默认数组并调用原始函数。

以下是示例代码:

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;
}
英文:

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;
}

答案2

得分: 3

我还需要知道传递的数组大小,而不传递其大小,这就是为什么我没有这样做的原因:int (*arr)[3]

这个解释对我来说没有意义。数组大小已经编码在指针类型中。只需通过指针间接引用,你会得到一个 int (&arr) [3]。示例:

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

因此,使用指向数组的指针是你问题的答案。

另一个选择是使用可选的 span:

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

虽然参数类型有点更多的文字,但这允许你直接传递一个数组,而不使用地址运算符。此外,这也允许传递其他连续的范围,而不仅仅是数组。


如果你在编译时知道你想要默认选项,那么我建议使用 Syed 回答中的重载解决方案,但如果选项在运行时确定,那就不适用。

英文:

> 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 (&amp;arr) [3]. Example:

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

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&lt;std::span&lt;int, 3&gt;&gt; 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.

huangapple
  • 本文由 发表于 2023年6月18日 23:09:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76501190.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定