-1

I created a simple template. It gives me a warning: "No return, in function returning non-void".

template<typename T> struct test {
public:
    test & operator=(const T & new_value) {
        value = new_value;
    }
    operator T() const {
        return value;
    }
private:
    T value;
};

The warning is pointing at

test & operator=(const T & new_value) {
    value = new_value;
}

Can anyone offer some advice on how to fix this warning.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
2607
  • 4,037
  • 13
  • 49
  • 64
  • 11
    Uh.. return something? (Probably `*this`) – ildjarn Feb 21 '12 at 21:56
  • Thanks, it works now. If I return *this, what does it actually return? – 2607 Feb 21 '12 at 21:58
  • 6
    I think it's time you started over with [a good book](http://stackoverflow.com/q/388242/636019)... – ildjarn Feb 21 '12 at 21:59
  • @2607, you already know the answer. You know `this` is a pointer to the object the function was called on, and you know `*` results in a reference to the pointer it's applied to. The method you're working in is a member of the `test` class, so `this` will point at a `test` object. Furthermore, you know `test &` is the return type of the function you're writing, and it signifies a reference to a `test` object. Thus, when you say `*this` and you get a reference to the object the method was called on, you'll get a reference to a `test` object, perfect for a function that returns `test&`. – Rob Kennedy Feb 21 '12 at 22:15

3 Answers3

2

As the warning rightly says, your function isn't returning anything, even though it promises to return a test &. Simply end your function with return *this;, as is the usual convention for assignment operators.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
1

Your operator= function doesn't return anything, when it's suppose to be returning a reference to an object of type test. So change this:

test& operator=(const T & new_value) 
{
    value = new_value;
}

To this:

test& operator=(const T & new_value) 
{
    value = new_value;

    //dereference the "this" pointer to get a lvalue reference to
    //the current object
    return *this; 
} 

Note that by accessing the implicit this pointer of a class (that is the pointer that is pointing to the instance class itself in memory that a method is being called on), and dereferencing it, you are accessing a lvalue reference of the class instance. So if you are returning an lvalue reference from your class method, that reference can then be passed to other functions that take references as arguments, and/or other methods can be called on that returned class instance. This allows the operator= to be used in "chains" of functions and method calls, where after the operator= method is called, another method is called on the resulting modified object instance. For instance, you could do something like:

test<int> a;
a.value = 5;

int b = (a = 6) + 5; //outputs the value 11

If you had created a print() method for your test object, you could also do something like the following:

test<int> a;
a.value = 7;
(a = 8).print();

This code returns the test class instance a after the operator= method, and then calls the print() method on that instance, printing out the value 8.

Jason
  • 31,834
  • 7
  • 59
  • 78
0

Your compiler is telling you that your operator= overload is incorrect. Writing an operator= overload function requires that you follow a specific format.

Test & Test::operator=( const Test & r )
{
    if( this != &r )
    {
        // copy member variables and initialize here
        m_MemberVar = r.m_MemberVar;
        ...
    }

    return *this;
}

NB

  1. You must return *this.
  2. It's good practise to ensure that you avoid copying an object to itself with

    if(this != &r){...}
    
  3. If you overload operator= for an object, you'll almost certainly need to provide a copy constuctor too. e.g.

    Test::Test( const Test & r ){...}
    

EDIT

You'd asked "if I return *this, what does it actually return" Well, It returns a reference to the current object. E.g. in the operator= overload definition above, the return type is declared as Test & (Test object reference).