我有一个模板链接列表实现,其中
T List<T>::GetElementFromHead()
从列表的头部返回值。列表为空时应返回什么值。
template <class T>
T List<T>::GetElementFromHead()
{
T element;
if (!IsEmpty())
{
element = Head->value;
}
return element;
}
如果IsEmpty()
返回 true ,则return element;
会抛出异常。
在这种情况下,如何返回null或空值?
答案 0 :(得分:3)
列表为空时应返回什么值。
有两个合理的选择。
谁在乎呢。设置为GetElementFromHead()
仅在列表不为空时才被调用的前提条件,然后您可以写:
template <class T>
T& List<T>::GetElementFromHead() {
return Head->value;
}
这有几件好事。没有副本。它很快。如果我愿意,我可以修改值。没有额外的分支,因为您需要用户预先完成。无需担心错误的情况或提出合理的哨兵价值。如果您返回T{}
,如果T
为int
且该列表可能正常0
,该怎么办?用户如何区分&#34;真实&#34; 0
和&#34;假&#34; 0
?
这就是标准库实现list::front()
,vector::front()
等的方式。像标准库那样做通常是一个很好的决定。
封装返回值本身,无论它是否为实际值:
template <class T>
std::optional<T> List<T>::GetElementFromHead() {
if (!IsEmpty()) {
return Head->value;
}
else {
return std::nullopt;
}
}
(如果使用boost::optional
,则最后一行应返回boost::none
)。通过这种方式,返回值本身可以清楚地表明我们处于什么状态 - 我们要么拥有一个值,要么该值是列表的前面,或者我们没有值。再一次,没有必要提出哨兵。
另一个版本是在失败时返回T*
和nullptr
。这样做的好处是它不会产生副本或要求T
可以复制构造。