0

Im new at coding and I get "error:no return statement in function returning non-void" for this code:

template <class T>
T Stack<T>::pop()
{
  `myStack.pop_front();
}
template <class T>
T Stack<T>::peek() const
{
  myStack.front();
}

any ideas of what I am doing wrong? thanks!

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
rovertL
  • 1
  • 1
  • 1

6 Answers6

3

The function signature:

template <class T> T Stack<T>::pop()

tells the compiler that your function will return a type T however your function actually does not return any value and hence the compiler gives you the waring of a possible silly mistake on your part.

So you in your case you need to make sure that the statements,
myStack.pop_front(); & myStack.front(); actually return a type T.

Assuming you are using some standard library container, pop_front(); just removes the first element in the container it does not return anything.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 2
    "it does not return anything" - the reason being that returning `T` by value might involve copying a `T`, and for some types `T` that might throw an exception, which means the front of the stack has been removed but you have no way of seeing the value (because the function threw instead of returning it), which is bad. So your `Stack` class should probably do likewise, make `pop` return void. If for some reason it must return a value then you'd do `{ T t = peek(); myStack.pop_front(); return t; }` and document that the function only offers the basic exception guarantee. – Steve Jessop Feb 29 '12 at 09:49
2

You must add the return keyword:

template <class T>
T Stack<T>::pop()
{
  return myStack.pop_front();
}
template <class T>
T Stack<T>::peek() const
{
  return myStack.front();
}

or something similar, depending on your imlementation of stack.

RED SOFT ADAIR
  • 12,032
  • 10
  • 54
  • 92
1

While the shortviewed solution is to return a value, it is better if a pop() is of type void.

template <typename T>
void Stack<T>::pop() {
    ...
}

The reason is that you cannot write an exception safe pop()-function that returns something:

template <typename T>
T Stack<T>::pop() {
    T foo = stor_.top(); // May throw.
    stor_.pop(); // This line shall never throw.
    return foo;  // May throw.
}

The second line (with the pop()) should never throw something, because destructors shall not throw. So it is sane to assume that line is nothrow and will always succeed (except when you pop an empty container).

The first and third line may throw because data is being copied.

Now imagine that

    T foo = stor_.top(); // May throw.
    stor_.pop(); // This line shall never throw.

run flawlessly: You have a value ready to be returned, and you have successfully changed the state of the holding object.

But then

    return foo;  // May throw.

bang it throws an exception. What happened:

  • The function did not succeed, the caller got nothing except an exception
  • Still yet, the state of the object has been modified.
  • And noone has an up to date copy of the lost object anymore which typically contains critical business data that the boss phoned over seconds ago before having a fatal accident

This is contradictory to Abrahams Guarantees:

  • The no-throw guarantee: that the operation will not throw an exception.

  • The strong guarantee: that the operation has either completed successfully or thrown an exception, leaving the program state exactly as it was before the operation started.

  • The basic guarantee: that the invariants of the component are preserved, and no resources are leaked. Often referred to as the weak guarantee, because following an exception the system is left in a safe, but unknown, state.

And with a pop() that returns a value, you cannot guarantee that no information is lost.

See also GotW #8 and GotW #82

Community
  • 1
  • 1
Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130
0

Your signature asks you to return an object of type T.

template <class T> T Stack<T>::pop()

To break this down a bit template <class T> means that for each class that you put in for T another copy of the code will be generated. For example if you did

Stack intStack; Stack doubleStack;

The compiler would generate two copies of you Stack class: one specialised for int and another for double.

So when you write

template <class T>
T Stack<T>::pop()
{
  myStack.pop_front();
}

you need to return an object of the specialised type. pop_front() only removes the first element. You need to access it remove the first item then return it.

This might not be the best way of doing it but to illustrate my point

template <class T>
T Stack<T>::pop()
{
  T tmp = myStack.front();
  myStack.pop_front();
  return tmp;
}
Jim Jeffries
  • 9,841
  • 15
  • 62
  • 103
0

As you signature indicate that function is returning type T, you should change your code to code like following for both function.

template <class T>
T Stack<T>::peek()
{
  return myStack.front();
}
Kunal
  • 3,475
  • 21
  • 14
0

This will work:

 template <class T>
    void Stack<T>::pop()
    {
      `myStack.pop_front();
    }
    template <class T>
    void Stack<T>::peek() const
    {
      myStack.front();
    }

Or:

template <class T>
T Stack<T>::pop()
{
  `myStack.pop_front();
  // return something of type T
}
template <class T>
T Stack<T>::peek() const
{
  myStack.front();
  //return something of type T
}
Rohit Vipin Mathews
  • 11,629
  • 15
  • 57
  • 112