返回无效引用

Returning an invalid reference

本文关键字:引用 无效 返回      更新时间:2023-10-16

有时当我用C++编程时,我希望每个变量都有一个undefined值,比如Javascript!。例如,当我为数组的越界元素返回值时,返回undefined而不是抛出异常很有用,或者:

template <typename T, int SIZE>
class MyArray
{
  T arr[SIZE];
  static T badref;
public:
  T &operator[](int i)
  {
    if (i >=0 && i < SIZE)
      return arr[i];
    else
      throw std::string("OUT-OF-BOUNDS"); // or: return badref; !!
  }
};

另一个肮脏(在我看来)选项是将预查找变量的引用作为错误引用变量返回。我知道我们不能将null或类似的东西分配给引用变量。

是否有另一种格式良好的模式来返回引用,其中调用方能够找出返回的值无效?

编辑:我不是说pointer

你可以使用 boost::optional,正如他的评论中提到的@chris。它是Boost库的一部分。有关更多详细信息,请参阅此页面。

修改MyArray类:

template <typename T, int SIZE>
class MyArray
{
  T arr[SIZE];
public:
  optional<T&> operator[](int i)
  {
    if (i >=0 && i < SIZE)
      return optional<T&>(arr[i]);
    else
      return optional<T&>();
  }
};

用法:

MyArray<int>() array;
// fill array with data
optional<int&> result = array[0];
if (result) {
    // item was found
} else {
    // index out of bounds
}

我希望每个变量都有一个未定义的值,比如 Javascript!

指针只有一个"未定义"值 (nullptr)。引用(根据定义)是指向有效实例的东西。

要返回对静态对象的引用,您应该在运算符的 const 值和非 const 值之间分开:

template <typename T, int SIZE>
class MyArray
{
  T arr[SIZE];
  static T badref;
public:
  T &operator[](int i)
  {
    if (i >=0 && i < SIZE)
      return arr[i];
    else
      // returning ref here would allow clients to write:
      // MyArray<int> a;
      // a[-1] = 5; // valid if you return a non-const reference
      throw std::string("OUT-OF-BOUNDS");
  }
  const T &operator[](int i) const
  {
    if (i >=0 && i < SIZE)
      return arr[i];
    else {
      // MyArray<int> a;
      // a[-1] = 5; // will not compile (cannot assign to const)
      static const T invalid = T();
      return invalid;
    }
  }

};

无论您想到什么,您的解决方案都需要适合类型系统。因此,您的函数签名必须明确表示(以这种或那种方式)结果可能是 T,但也可能是其他东西。

常见的方法是:

    不要返回值
  • ,而是返回状态代码并通过"out"参数(指针或引用)输出值:

    bool tryGet(int i, T& result);
    
  • 返回一个元组(状态、值),如下所示:

    std::tuple<bool, T> get(int i)
    

    (如果无法获取,则认为第二个元组元素无关紧要 - 要求 T 具有默认构造函数)

  • 使用boost::variant(灵活,但需要提升)

  • 使用boost::optional(上述的简化版本,当您只需要"要么T要么什么都不需要")

引用的主要目标是避免无效 (NULL) 值,同时允许函数修改其参数并防止复制数据。 如果需要 NULL 值,请使用指针。

相关文章: