Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

operator+

22 views
Skip to first unread message

Doug Mika

unread,
Jun 16, 2015, 1:43:33 PM6/16/15
to
I have heard of having operator+ inside a class, to define the + operation on objects of that class. However, what if we have defined such an operator outside of any class(and on top of that we make it a template)? And, what is the purpose of -> and what it points to in:

template<class T, class U>
auto operator+(const Matrix<T>& a, const Matrix<U>& b) -> Matrix<decltype(T{}+U{})> {
Matrix<decltype(T{}+U{})> res;
for (int i=0; i!=a.rows(); ++i)
for (int j=0; j!=a.cols(); ++j)
res(i,j) += a(i,j) + b(i,j);
return res;
}

Richard

unread,
Jun 16, 2015, 2:03:41 PM6/16/15
to
[Please do not mail me a copy of your followup]

Doug Mika <doug...@gmail.com> spake the secret code
<06240885-10b9-4a28...@googlegroups.com> thusly:

>I have heard of having operator+ inside a class, to define the +
>operation on objects of that class. However, what if we have defined
>such an operator outside of any class(and on top of that we make it a
>template)? And, what is the purpose of -> and what it points to in:
>
>template<class T, class U>
>auto operator+(const Matrix<T>& a, const Matrix<U>& b) ->
>Matrix<decltype(T{}+U{})> {

See item (2): <http://en.cppreference.com/w/cpp/language/auto>

A template function often wants to say "my return type is the type
resulting from some expression; dear compiler please figure that out
for me".

The mechanism for supporting this in C++11 is to declare the return
type of the template function "auto" and then use -> to specify the
return type with decltype.
<http://en.cppreference.com/w/cpp/language/decltype>

The "trailing return type" syntax can also be used with any function
declaration, not just template functions. See
<http://en.cppreference.com/w/cpp/language/function>
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Doug Mika

unread,
Jun 16, 2015, 4:52:41 PM6/16/15
to
My first question was indeed, what is ->, that's clear now.
But the question that remains is why would we overload the + operator on a class C, for example, outside of the class? Why not include operator+ inside our class C definition?

Richard

unread,
Jun 16, 2015, 5:11:59 PM6/16/15
to
[Please do not mail me a copy of your followup]

Doug Mika <doug...@gmail.com> spake the secret code
<e90d32f4-65f1-4a3b...@googlegroups.com> thusly:

>My first question was indeed, what is ->, that's clear now.
>But the question that remains is why would we overload the + operator on
>a class C, for example, outside of the class? Why not include operator+
>inside our class C definition?

Prefer small, simple classes over large ones.

If you force everything to be a member function, even those functions
that aren't *required* to be a member function, then you end up with
the rather large bloated class that is std::string. The rule of thumb
is: if you can implement something as a free function (i.e. not a
member function) using the public interface of a class then prefer that
over a member function.

This goes hand-in-hand with the advice for namespaces -- the only thing
not in a namespace is your implementation of main(). You put the class
and its associated free functions all inside a namespace and then they
don't get in the way of other free functions for other classes and ADL
guarantees that the right operator+ is selected when used with that
class.

Victor Bazarov

unread,
Jun 16, 2015, 5:13:35 PM6/16/15
to
On 6/16/2015 4:52 PM, Doug Mika wrote:
> [..] the question that remains is why would we overload the +
> operator on a
class C, for example, outside of the class? Why not include operator+
inside our class C definition?
>

It's a design choice. Two-operand operators are often defined outside
of the class to allow conversions to take place on either operand, not
just the right-hand one.

V
--
I do not respond to top-posted replies, please don't ask

Doug Mika

unread,
Jun 16, 2015, 5:17:16 PM6/16/15
to
What sort of conversions are we speaking of?

Victor Bazarov

unread,
Jun 16, 2015, 5:22:38 PM6/16/15
to
<sigh>

What book are you reading that doesn't explain conversions?

struct ConvertibleFromInt {
ConvertibleFromInt(int) {}
};

...
ConvertibleFromInt c = 42;

Now compare

struct PlusAsMember {
PlusAsMember(int) {}
PlusAsMember operator+(PlusAsMember const& rhs) const;
};
...
PlusAsMember p(42);

p + 777; // OK
777 + p; // NOT OK

with this

struct PlusOutside {
PlusOutside(int) {}
};

PlusOutside operator+(PlusOutside const& o1,
PlusOutside const& o2);

...
PlusOutside p(42);

p + 777; // OK
777 + p; // OK

In order to try those things, add code to make them complete programs,
then compile.
0 new messages