返回无效的引用

时间:2012-11-16 12:20:43

标签: c++

有时当我用C ++编程时,我希望每个变量都有一个undefined值,就像Javascript! 例如,当我为数组的out-of-bounds元素返回一个值时,返回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

4 个答案:

答案 0 :(得分:5)

你可以在评论中提到使用boost :: optional作为@chris。它是Boost libary的一部分。有关详细信息,请参阅this page

修改后的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
}

答案 1 :(得分:3)

  

我希望每个变量都有一个未定义的值,比如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;
    }
  }

};

答案 2 :(得分:2)

无论您如何看待,您的解决方案都需要适应类型系统。所以你的函数签名必须明确地说(这样或那样)结果可能是T,但也可能是其他东西。

常见的方法是:

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

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

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

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

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

  • 使用boost::optional(上述更简单的版本,当您只需要“T或无”时)

答案 3 :(得分:0)

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