dav
dav

Reputation: 936

C++: How to restrict an operator overload to class scope?

Suppose I have a class A that performs elementwise std::pair addition often. For convenience, I want to overload operator+ for two std::pairs like so:

template <typename T, typename U>
std::pair<T, U> operator+(std::pair<T, U> left, std::pair<T, U> right)
{
    return {left.first + right.first, left.second + right.second};
}

But, I don't want to introduce this overload outside the scope of A, since it's really only useful inside A. So I might do something like:

class A
{
    // ...
    template <typename T, typename U>
    std::pair<T, U> operator+(std::pair<T, U> left, std::pair<T, U> right)
    {
        return {left.first + right.first, left.second + right.second};
    }
    // ...
};

Unfortunately this doesn't work since to C++ this looks like a member operator overload of the + operator on A with two additional arguments (fails to compile since operator+ only expects one argument as a member overload).

What's the right way to do this?

Upvotes: 0

Views: 159

Answers (1)

Sam Varshavchik
Sam Varshavchik

Reputation: 118310

Presumably you follow disciplined programming practices, and you have a translation unit that implements only A's methods and nothing else.

In that case, putting this overload into an unnamed namespace, at the beginning of A.cpp should do the trick:

namespace {

    template <typename T, typename U>
    std::pair<T, U> operator+(std::pair<T, U> left, std::pair<T, U> right)
    {
        return {left.first + right.first, left.second + right.second};
    }
}

std::pair<int, char> A::grobthem(const std::pair<int, char> &a, const std::pair<int, char> b)
{
    return a+b;
}

Multiple translation units may use their own definition of the + overload, internally, without conflicting with each other; although if they are logically identical this will result in unnecessary code bloat.

Upvotes: 2

Related Questions