8

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

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

4 回答 4

5

您可以使用 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
}
于 2012-11-16T12:31:14.093 回答
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;
    }
  }

};

于 2012-11-16T13:02:34.883 回答
2

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

常见的方法是:

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

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

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

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

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

  • 使用boost::optional(上面的简单版本,当你只需要“要么 T 要么什么都没有”时)
于 2012-11-16T12:50:40.960 回答
0

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

于 2012-11-16T14:59:40.610 回答