如何在C++中返回Null作为引用

How to return Null as reference in C++?

本文关键字:Null 引用 返回 C++      更新时间:2023-10-16

我做了一些最小代码

vector<int> items = {1, 2, 5, 0, 7};
int& getAtSafe(unsigned n) {
if (n < items.size() && items[n] != 5) return items[n];
else // ???
}

但是,当我们找不到需要的项目时,如何将其返回为null
P.S.原始任务是搜索属性等于.的项目

不接受异常变体。我不需要暂停程序
例如,用户键入索引,每次出错时,用户都会得到"错误输入">

如果函数检查索引,那么在这种情况下的一般方法是抛出异常std::out_of_range.

考虑到在类模板std::vector中已经存在成员函数at

如果您可能不使用异常,并且任务是

p.S.原始任务正在搜索属性等于.的项目

然后您可以使用返回迭代器的标准算法std::find_if,也可以编写自己的函数来返回与搜索元素相对应的索引。如果没有这样的元素,那么返回向量的大小,例如

#include <iostream>
#include <vector>
template <typename Predicate>
std::vector<int>::size_type find_if( const std::vector<int> &v, Predicate predicate )
{
std::vector<int>::size_type i = 0;
while ( i != v.size() && !predicate( v[i] ) ) ++i;
return i;
}
int main() 
{
std::vector<int> items = {1, 2, 5, 0, 7};
auto i = ::find_if( items, []( const auto &item ) { return item % 2 == 0; } );
if ( i != items.size() ) std::cout << items[i] << 'n';
return 0;
}

C++具有值语义。有nullptrs,但没有空值。引用总是引用一些东西。呃,不能有对null的引用。

你有几个选择:

  • 抛出异常。你拒绝它们的理由毫无根据。std::vector::at正是这样做的(但我想您的代码只是更一般情况下的一个示例(
  • 返回一个可以是nullptr的指针(不推荐使用,因为这样可以将正确处理它的责任放在调用者身上(
  • 返回CCD_ 8。这再次迫使调用方处理"未返回值"的情况,但与返回nullptr相反,调用方得到了一个设计良好的接口,很难使用错误
  • 返回迭代器。end通常用于在整个标准库中发出"未找到元素"的信号,因此如果您也这样做,则不会有什么意外
  • 也许这不仅仅是一个不同情况的例子,那么您应该使用std::vector::at而不是手写功能,并使用它

p.S.原始任务正在搜索属性等于.的项目

您应该使用std::find在容器中查找项目。当找不到元素时,返回容器的end

在不更改原型的情况下,您只能抛出异常。

如果可以选择更改原型,您可以:

  • 返回一个指针(并使用nullptr作为sentinel(
  • 返回迭代器(并使用items.end()作为sentinel(
  • 返回一个std::optional<std::reference_wrapper<int>>(并使用值的缺失作为sentinel,然后需要C++17或boost(

C++中引用的一个用例是确保没有空指针。因此,根据定义,不可能将null作为引用返回。

然而,可以考虑不同的策略:

  • 返回迭代器:使用std::end(items)作为空值
  • 按值返回
  • 如果没有元素有效,则引发异常