Home How to write a commutable overloaded arithmetic operator for a template nested class?
Reply: 1

How to write a commutable overloaded arithmetic operator for a template nested class?

Nighteen
1#
Nighteen Published in 2018-01-12 01:40:06Z

I successfully built an overloaded operator+(Global left, int right) for a template class in global scope named Global.

template <typename T>
class Global {
public:
    Global operator+(const int& right) const
    {
        cout << "Using Global overloaded operator+" << endl;

        return *this;
    }
};

Since addition is commutative, I also created the other overloaded operator+(int left, Global right) to allow the commutable operation.

template <typename T>
Global<T> operator +(int left, Global<T> right)
{
    return right + left;
}

Here is my attempt to do the same thing for a Nested Class.

template <typename T>
class Container {
public:
    class Nested {
    public:
        Nested operator+(const int& right) const
        {
            cout << "Using Nested overloaded operator+" << endl;

            return *this;
        }
    };
};

template <typename T> // The following line is critical
typename Container<T>::Nested operator+(int left, typename Container<T>::Nested right)
{// Both 'typename' are necessary to avoid extra compilation errors
    return right + left;
}

Now when I try to execute the following code to test the operator overloads, I get some compilation errors when trying to use the commutable operator+ from the Nested class, mainly "Error C2783 - 'Container::Nested operator +(int,Container::Nested)': could not deduce template argument for 'T'", but also "Error E0349 - no operator "+" matches these operands".

int main(void)
{
    Global<int> global;

    global + 2; // Works perfectly
    2 + global; // Works perfectly

    Container<int>::Nested nested;

    nested + 2; // Works perfectly
    2 + nested; // Compilation Error C2783 and E0349

    system("pause"); // Everything works fine without the line above

    return 0;
}

I am using Visual Studio 15.5.2 with /std:c++latest enabled. If possible, I would like the operator+ to be defined inside the Nested class definition.

Fureeish
2#
Fureeish Reply to 2018-01-12 11:54:07Z

As seen in this answer, the template deduction is far more complicated in this case than one might think. To fix this you can declare the function as friend inside your Nested class, like so:

template <typename T>
class Container {
public:
    class Nested {
    public:
        Nested operator+(const int& right) const
        {
            std::cout << "Using Nested overloaded operator+" << std::endl;

            return *this;
        }
        // moved here and declared as friend, instead of declaring it somewhere else
        friend Nested operator+(int left, Nested right)
        {
            return right + left;
        }
    };
};

By doing this, you also avoid using double typename and Container<T>:: (thanks @Jarod42) in the signatue.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.330223 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO