以参考方式返回作为& Int

时间:2018-02-04 00:03:17

标签: c++ reference return

所以我在这里有一些代码:

template <class T>
T& Array<T>::operator[](const int pos){
// Exit if pos is not valid.
if (pos < 0 || pos >= mSize) {
    return -1;
}
return mArray[pos];
}

我收到了这个错误:

error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'

我知道它正在发生,因为我在开头有参考&amp; T,如果它通过if语句无效,我返回-1。尽管我想拿出参考资料,但这是一个学校实验室,我无法调整原型。 所以基本上我的问题是:如果if语句在没有编辑任何引用的情况下通过,我如何让它退出-1?我知道我可能在某些时候已经学会了这个,但我有有点大脑放屁并且寻找最后一点没有产生任何结果。

2 个答案:

答案 0 :(得分:1)

这里的问题是界面设计。暂时让我们忽略一些技术细节,让我们假设执行任务的函数不返回引用,而是按值返回。我们假设它不是运算符[]而是一个名为GetValueAt的函数:

template <class T>
T Array<T>::GetValueAt(const int pos)

这个签名实质上告诉调用者“给我一个数字,然后我将返回数组中的相应元素”。重要的是要将这与另一种可能性区分开来,这种可能性是有一个函数说“给我一个数字,,如果确实对应于范围内的元素,我将返回该元素”。在这种情况下,签名可能类似于

template<class T>
std::optional<T> Array<T>::GetValueAt(const int pos)

std::optional<T>是一个可能确实包含T实例的类,或者它可能不包含任何内容。该签名识别出给定整数可能不在数组范围内的事实。它接受这是一个正常的用例,并为此做好准备。如果索引无效,则返回空std :: optional。

然而,第一个签名是“无论你给我什么索引,我都会给你一个参考”。它不会将索引超出范围的情况视为正常用例,而是将其视为意外的错误情况。在这种情况下,正确的方法是抛出异常,因为没有返回的参数可以正确表达发生的事情,即:

template <class T>
T Array<T>::GetValue(const int pos)
{
if (pos < 0 || pos >= mSize) {
    throw std::invalid_argument("index out of range");
return mArray[pos];
}

请注意,在这种情况下,您很想返回-1,但这并不能正确表达索引无效。 -1在某些情况下可能是有效值,因此不适合发出错误信号。

总而言之,我会写这样的方法:

template <class T>
T& Array<T>::operator[](const int pos)
{
if (pos < 0 || pos >= mSize) {
    throw std::invalid_argument("index out of range");
return mArray[pos];
}

答案 1 :(得分:0)

您不应该返回-1。即使T是可以从-1构造的类型,也不应该在错误上返回有效值。如何区分成功通话和失败通话?另外,如果T是一种无法从-1构建的类型,该怎么办?例如。 std::string

根据您的界面,您可以选择一些选项来表示该功能无法履行其职责:

  • 抛出异常(最佳选择)
  • 添加assert。这将以调试模式结束您的程序或在发布时导致未定义的行为。
  • 致电exit并结束该计划

为了完整起见,这里有一些其他选项,更多的是C-ish处理它的方式。通常没有人推荐。去寻找例外。

  • 添加额外参数(不是operator[]的选项)
  • 返回std::optional。进一步复杂的参考类型,如您的示例(std::optional<std::reference_wrapper<T>>
  • 返回一个(可能为null)指针。没有重新开始。
  • 设置static / global / tread_local变量(如errno)。