Subject: Re: [boost] SafeInt code proposal
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2009-06-22 17:06:01


AMDG

Niels Dekker - address until 2010-10-10 wrote:
> Steven Watanabe wrote:
>> I don't think that non-template friends should be defined inline in a
>> class template because they are always supposed to be instantiated
>> regardless of whether they are used or not (unlike ordinary members).
>
> Thanks, Steven. Do I understand correctly that when you look at the
> following example, you find the definition of operator+ preferable to
> operator- ?
>
> //////////////////////////////////////////////////////////
> template <typename> class safe_int;
>
> template <typename T>
> safe_int<T> operator+(safe_int<T>, safe_int<T>);
>
> template <typename T> class safe_int
> {
> public:
> friend safe_int operator+ <>(safe_int, safe_int);
>
> inline friend safe_int operator-(safe_int, safe_int)
> {
> throw "operator- not yet implemented.";
> }
> };
>
> template <typename T>
> safe_int<T> operator+(safe_int<T>, safe_int<T>)
> {
> throw "operator+ not yet implemented.";
> }
> //////////////////////////////////////////////////////////
>
> I still hesitate, because the non-template inline friend, operator-,
> appears to support implicit conversions more intuitively... I think.

Sorry. I reacted automatically, because of the problems that
I've had with inline friends. In this case, I think it's not a problem
to define them inline. The cases that cause problems are like:

template<class Iterator>
struct reverse_iterator {
    friend reverse_iterator operator+(typename Iterator::difference_type
n, reverse_iterator iter) {
        return(reverse_iterator(iter.base() - n)); // oops... early
error if Iterator is not a RandomAccessIterator
    }
};

For safe_int, you could only run into problem by both
a) supporting user-defined type. I don't see the point of this.
b) only requiring the underlying type to support division (e.g.) if
    the user tries to divide two safe_ints.

> Isn't support of such conversions (in a symmetrical way) the main
> reason to declare such operators as non-members, rather than as member
> functions?

Maybe. For me it's more important that the operators are defined
consistently and there is no way to overload an operator as a member
with the first argument being of a different type. In any case, it's
okay to support implicit conversions for both arguments or neither,
as far as I am concerned. It's the matter of supporting implicit
conversions
only for the second argument that makes the member operator really
unattractive.

In Christ,
Steven Watanabe