Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning an invalid reference

Tags:

c++

Sometimes when I'm programming in C++ I wish there was an undefined value for every variable something like Javascript!. For example when I'm returning a value for out-of-bounds element of an array, it was useful to return an undefined instead of throwing an exception, or:

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; !!
  }
};

Another dirty(In my opinion) option is returning a reference of a pre-defind variable as a bad-reference variable. I know we can not assign null or something like that to a reference variable.

Is there an another well formed pattern to return a reference where caller has the ability to find out the returned value is not valid?

EDIT: I'm not mean a pointer

like image 304
masoud Avatar asked Nov 16 '12 12:11

masoud


People also ask

What happens if you return a reference?

But return reference may cause memory allocation problem. Because a reference to the result will be passed out of the function as a reference to the return value, the return value cannot be an automatic variable. in this way, you could use returning reference safely.

What does returning a reference mean?

When a function returns a reference, it returns an implicit pointer to its return value. This way, a function can be used on the left side of an assignment statement.

Can reference be reassigned?

Remember, once you initialize a reference, you cannot reassign it. A reference practically stands for an object. You cannot make it 'point' to a different object.

Can reference be reset?

(C) Once a reference is created, it cannot be later made to reference another object; it cannot be reset. Explanation: We can create a constant reference that refers to a constant.


2 Answers

You can use boost::optional as @chris mentioned in his comment. It comes as a part of Boost libary. See this page for more details.

Modified MyArray class:

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&>();
  }
};

Usage:

MyArray<int>() array;
// fill array with data

optional<int&> result = array[0];
if (result) {
    // item was found
} else {
    // index out of bounds
}
like image 152
Miroslav Bajtoš Avatar answered Oct 26 '22 23:10

Miroslav Bajtoš


I wish there was an undefined value for every variable something like Javascript!

You only have an "undefined" value for pointers (nullptr). A reference is (by definition) something pointing to a valid instance.

To return a reference to a static object, you should separate between const and non-const values of your operator:

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;
    }
  }

};

like image 30
utnapistim Avatar answered Oct 27 '22 00:10

utnapistim