如何在 C++ 中将 return Null 作为引用?
How to return Null as reference in C++?
我做了一些最小的代码
vector<int> items = {1, 2, 5, 0, 7};
int& getAtSafe(unsigned n) {
if (n < items.size() && items[n] != 5) return items[n];
else // ???
}
但是当我们找不到需要的项目时,如何return将某些内容设为空?
P.S. 原任务正在搜索 属性 等于.
的项目
Exception variants not accepted. I do not need to pause the program.
As an example, user types index, and each time when it's wrong, the user gets "Bad input"
如果函数检查索引,那么在这种情况下的一般方法是抛出异常 std::out_of_range.
考虑到 class 模板中已经有成员函数 at
std::vector
。
如果你可能不会使用异常并且任务是
P.S. Original task is searching item with property equal to.
然后您可以使用标准算法 std::find_if
return 作为迭代器,或者您可以编写自己的函数 return 作为与搜索元素对应的索引。如果没有这样的元素,那么 return 向量的大小,例如
#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++ 中引用的一个用例是确保您没有空指针。所以根据定义,不可能return null作为参考。
但是,可以考虑不同的策略:
- Return迭代器:使用
std::end(items)
作为空值
- Return 按值
- 如果没有元素有效则抛出异常
在不改变原型的情况下,你被限制抛出异常。
如果可以选择更改原型,您可以:
- return 一个指针(并使用
nullptr
作为标记)
- return 一个迭代器(并使用
items.end()
作为标记)
- return 一个
std::optional<std::reference_wrapper<int>>
(并使用值的缺失作为标记,然后你需要 C++17 或 boost)。
C++ 具有值语义。有 nullptr
个但没有空值。引用总是引用某些东西。因此,不能引用 null。
您有几个选择:
- 抛出异常。你拒绝他们的论点是没有实际意义的。
std::vector::at
正是这样做的(但我想您的代码只是更一般情况下的示例)
- return 可以是
nullptr
的指针(不推荐,因为这样你就把正确处理它的责任放在了调用者身上)
- return一个
std::optional
。这再次迫使调用者处理 "no value returned" 的情况,但与 returning a nullptr
相比,调用者得到一个设计良好的接口,很难使用错误。
- return 一个迭代器。
end
通常用于在整个标准库中发出 "element not found" 信号,因此如果您也这样做就不会感到意外了。
- 也许这不仅仅是针对不同情况的示例,那么您应该使用
std::vector::at
而不是您的手写函数并完成它。
P.S. Original task is searching item with property equal to.
您应该使用 std::find
在容器中查找项目。找不到元素时容器的 returns end
。
我做了一些最小的代码
vector<int> items = {1, 2, 5, 0, 7};
int& getAtSafe(unsigned n) {
if (n < items.size() && items[n] != 5) return items[n];
else // ???
}
但是当我们找不到需要的项目时,如何return将某些内容设为空?
P.S. 原任务正在搜索 属性 等于.
Exception variants not accepted. I do not need to pause the program.
As an example, user types index, and each time when it's wrong, the user gets "Bad input"
如果函数检查索引,那么在这种情况下的一般方法是抛出异常 std::out_of_range.
考虑到 class 模板中已经有成员函数 at
std::vector
。
如果你可能不会使用异常并且任务是
P.S. Original task is searching item with property equal to.
然后您可以使用标准算法 std::find_if
return 作为迭代器,或者您可以编写自己的函数 return 作为与搜索元素对应的索引。如果没有这样的元素,那么 return 向量的大小,例如
#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++ 中引用的一个用例是确保您没有空指针。所以根据定义,不可能return null作为参考。
但是,可以考虑不同的策略:
- Return迭代器:使用
std::end(items)
作为空值 - Return 按值
- 如果没有元素有效则抛出异常
在不改变原型的情况下,你被限制抛出异常。
如果可以选择更改原型,您可以:
- return 一个指针(并使用
nullptr
作为标记) - return 一个迭代器(并使用
items.end()
作为标记) - return 一个
std::optional<std::reference_wrapper<int>>
(并使用值的缺失作为标记,然后你需要 C++17 或 boost)。
C++ 具有值语义。有 nullptr
个但没有空值。引用总是引用某些东西。因此,不能引用 null。
您有几个选择:
- 抛出异常。你拒绝他们的论点是没有实际意义的。
std::vector::at
正是这样做的(但我想您的代码只是更一般情况下的示例) - return 可以是
nullptr
的指针(不推荐,因为这样你就把正确处理它的责任放在了调用者身上) - return一个
std::optional
。这再次迫使调用者处理 "no value returned" 的情况,但与 returning anullptr
相比,调用者得到一个设计良好的接口,很难使用错误。 - return 一个迭代器。
end
通常用于在整个标准库中发出 "element not found" 信号,因此如果您也这样做就不会感到意外了。 - 也许这不仅仅是针对不同情况的示例,那么您应该使用
std::vector::at
而不是您的手写函数并完成它。
P.S. Original task is searching item with property equal to.
您应该使用 std::find
在容器中查找项目。找不到元素时容器的 returns end
。