Hi!
This is just an example code:

#include<iostream>
using namespace std;

int& example()
{
    int a=5;
    return &a;
}

int main()
{
    cout << example();
}

But I'm getting this error:
Error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int*'

&a evaluates to a pointer to int rather than int, therefore a reference to int is an incompatible type. Further, returning a reference to a non-static local variable is an extremely bad idea because the local variable is destroyed after the function returns; the reference will refer to a non-existent object.

I know it can be solved if function is defined as "int* example()", but in prototype of that task, function is defined as "int& example()". Is it then impossible to do it like that (which would mean that prototype is wrong), or there is some way?

I know it can be solved if function is defined as "int* example()"

The error will go away, but the underlying problem will remain. You're referring to an object that no longer exists. This is the dangling pointer or dangling reference problem.

If int a is global constant, how to do it then?

The real question is what do you want that function to accomplish? Because right now it's completely nonsensical.

Real task is something like this: there is a Stack (defined as class), with protected "array" (actually, pointer to dinamically alocated array) called container, which has a function called "int& top()", which returns reference of last element in that array. Something like this:

#include<iostream>
using namespace std;

class Stack{
    protected:
      size_t capacity;
      int size;
      int* container;
    public:
      Stack();
      ~Stack(){delete[] container;}

      void push(int broj);
      void pop();
      int* top();

      bool is_empty() const;
};

Stack::Stack()
{
    size=0;
    container=new int[4];
    capacity=4;
}

int* Stack::top()
{
    return &container[size-1];
}

bool Stack::is_empty() const
{
    if(size==0) return true;
    else return false;
}

void Stack::push(int broj)
{
    if(size==capacity){
        capacity*=2;
        int* novi_niz=new int[capacity];
        for(int i=0;i<size;i++) novi_niz[i]=container[i];
        delete[] container;
        container=novi_niz;
    }
    container[size]=broj;
    size++;
}

void Stack::pop()
{
    if(size==capacity/2){
        capacity/=2;
        int* novi_niz=new int[capacity];
        for(int i=0;i<size;i++) novi_niz[i]=container[i];
        delete[] container;
        container=novi_niz;
    }
    size--;
}

int main()
{
    Stack P;

    P.push(13);
    P.push(2);
    P.push(4);
    P.pop();

    cout << "Reference of last element in stack: " << P.top() << endl;

    return 1;
}

PS: I deleted some parts of code
Originally, it should be int& top(), which wont work in this case.

Edited 2 Years Ago by ivan3510

That makes much more sense, a realistic example is far more helpful than a broken example. You simply need to remove the address-of operator and returning a reference will work in this case because the array has the same lifetime as the stack object:

int& Stack::top()
{
    return container[size-1];
}

I tried this (even before actually), but then I get an element on place "size-1", and not its address. So, I dont know what is problem then.

Why would you want its address? That's meaningless to the caller of the method. Anyway, you can get the address on the caller's side using the updated code from my previous post:

cout << "Reference of last element in stack: " << &P.top() << endl;

Oh, ok. Thanks a lot.
I know it's meaningless, it's just a task from university.

But then, what does actually "int& top()" return (or, why does it have that &, it could work without it also)? (it doesnt return address, cause then, it wouldnt be needed to write in cout "&P.top()")

I understood now (it was mistake by them, they said that "int& top()" returns reference, which is wrong, it returns value by reference).

This question has already been answered. Start a new discussion instead.