mlikj2006
mlikj2006

Reputation: 191

return statement followed by initializer list

As I was reading a tour of C++ (3rd edition) I came across the following examples using the complex class (section 4.2).

Within the complex class definition:

complex& operator+=(complex z)
{
    re += z.re;
    im += z.im;
    return *this;
}

defined separately from class definition:

complex operator+(complex a, complex b)
{
    return a += b;
}

complex operator-(complex a)
{
    return { -a.real(), -a.imag() };
} // unary -
  1. Can someone help me make sense of why in the operator+ implementation, the author makes a call to operator+=, which changes the value of the complex number object that is making the call? If I were to evaluate the express a+b, would I expect the value a to be altered?

  2. Also, for the case of operator-, I am confused about the statement:

    return { -a.real(), -a.imag() };
    

Is the author using an initializer list after the returns statement? If so, can it be done without specifying the name of the object it is initializing?

Thanks in advance.

Upvotes: 0

Views: 1617

Answers (1)

Praetorian
Praetorian

Reputation: 109119

operator+ is delegating to operator+= to avoid having to maintain two function definitions. The argument to operator+ is not being modified because the operator makes local copies of the arguments by accepting them by value, instead of by reference. So the argument remains unmodified in the context of the caller.


The following statement

return { -a.real(), -a.imag() };

is using copy-list-initialization from a braced-init-list to construct a complex object using the constructor that takes real and imaginary value. This is a C++11 addition, and works because the std::complex constructor in question is not explicit.

How this works is explained in [dcl.init.list]/3 and [over.match.list]/1. Any constructors of std::complex that take an std::initializer_list<T> argument, would be considered first. If no such constructor exists (which is the case with std::complex), or if the constructor is not viable for the types of the arguments in the braced-init-list, other constructors of std::complex will be enumerated, and the best match selected via overload resolution.

Upvotes: 6

Related Questions