简体   繁体   中英

Operator overload of class wrapped in smart pointers

I've been trying to make some operator overloads (* and +) on a class which is wrapped in smart pointers.

auto p = std::make_unique<Polynomial<T>>();

When I try to overload it using normal overloading, it obviously asks for the smart pointer types.

Edit, so:

std::unique_ptr<Polynomial<T>> operator+(const std::unique_ptr<Polynomial<T>>& right);

template<class T>std::unique_ptr<Polynomial<T>> Polynomial<T>::operator+(const std::unique_ptr<Polynomial<T>>& right) {
    //Do stuff
}

And the error:

尝试使用+运算符时出错

So how do you go about overloading the normal operators when the class is encapsulated in a smartpointer?

Don't.

Run those operations on the pointees, not on the pointers:

*p = *p + *p

It would be very confusing for users of your code if suddenly pointers had completely different and unexpected semantics.

It would be confusing for you, too.

For a direct answer to your question, I agree with @LightnessRacesinOrbit: Just don't . But the reason to write another answer is that the question you are asking sounds a bit like an XY-problem to me.

You have a class Polynomial<T> but you expect the user to wrap it in a smart pointer? This is fishy as a sane design would just expect the user to work with Polynomial directly, hence providing normal operators that work on that type directly.

Take a step back and think about why you think a smart pointer would be used/needed/helpful. Often, this is done for presumed efficiency reasons, right? But that just means you should rethink how you implemented Polynomial itself. Look into the following:

  • Does Polynomial have move-constructor and -assignment? If not, implement it.
  • What about the stored data? Maybe the internal storage should be managed by a smart pointer. Together with move-semantics, this can lead to very efficient operations.
  • For operator overloading, implement a+=b; , use a library to have a+b generated for you. Check Boost.Operators or my df.operators , the latter is also move-aware.

With the right implementation, the urge to use std::unique_ptr<Polynomial<T>> should go away :)

So how do you go about overloading the normal operators when the class is encapsulated in a smartpointer?

Just declare them as you would normally:

template<typename T>
Polynomial<T> operator*(Polynomial<T> lhs, Polynomial<T> rhs) { ... }

template<typename T>
Polynomial<T> operator+(Polynomial<T> lhs, Polynomial<T> rhs) { ... }

and then given something like:

auto p = std::make_unique<Polynomial<int>>();
auto q = std::make_unique<Polynomial<int>>();

just call:

auto x = (*p) * (*q);
auto y = (*q) + (*p);

Live demo


The error you provided:

在此输入图像描述

is due to the fact that your operator overloading:

std::unique_ptr<Polynomial<T>> operator+(const std::unique_ptr<Polynomial<T>>& right);

is overloading the unary operator+ for expressions like +x .

And the other:

template<class T>
std::unique_ptr<Polynomial<T>> Polynomial<T>::operator+(const std::unique_ptr<Polynomial<T>>& right) {
    //Do stuff
}

is overloading operator+ for operands of type Polynomial<T> and std::unique_ptr<Polynomial<T>> .

Therefore given two unique_ptr<Polynomial<T>> , namely x and y , the following expression:

x + y

does not find an overload resolution for operator+ .

I also highly discourage the overloading of operators for standard library types.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM