模板对象的赋值和加法重载

Assignement and addition overload for template objects

我正在尝试同时学习模板和重载。我已经编写了下面的代码,但我无法使用内置类型对数据对象进行赋值。我做错了什么以及如何解决它,但更好的是,可以导致不调用中间复制构造函数的最佳实践是什么?

我想要所有可能的算术运算。我想如果我对其中一个(例如+)做对了,那么其他人也会有同样的原则。

我需要 Copy/Move 构造函数和赋值吗?

#include <iostream>
#include <concepts>

template<typename T>
requires std::is_arithmetic_v<T>
class Data {
    private :
    T d;
    
    public: 
    Data(const T& data) : d{data}{
        std::cout << "Constructed Data with: " << d << std::endl;
    }
    Data(const Data& other) = default;
    ~Data() {
        std::cout << "Destructed: " << d << std::endl;
    }

    void operator+(const T& other) {
        this->d += other;
    }

    Data operator+(const Data& other) {
        return (this->d + other.d);
    }

    Data operator=(const Data& other) {
        return(Data(d + other.d));
    }

    void operator=(const T& t) {
        this->d += t;
    }

    Data operator=(const T& t) { // FAIL
        return Data(this->d + t);
    }
};

int main() {

Data a = 1;
Data b = 2;

Data c = a + b;
Data d = 10;
d = c + 1; // how to do this? FAIL

}

Compile Explorer Link

问题是您同时定义了 void operator=(const T& t)Data operator=(const T& t)。 C++ 不允许两个函数仅在 return 类型上有所不同,因为无法确定何时应调用哪个重载。

对于初学者,您不能仅通过 return 类型重载运算符,如

void operator=(const T& t) {
    this->d += t;
}

Data operator=(const T& t) { // FAIL
    return Data(this->d + t);
}

至于其他问题则在此声明

d = c + 1;

由于运算符

的声明,表达式 c + 1 具有 return 类型 void
void operator+(const T& other) {
    this->d += other;
}

运算符应该像

那样声明和定义
Data operator +(const T& other) const
{
    return this->d + other;
}

运算符可以重载,如下所示

template<typename T>
requires std::is_arithmetic_v<T>
class Data {
private:
    T d;

public:
    Data( const T &data ) : d{ data } {
        std::cout << "Constructed Data with: " << d << std::endl;
    }
    Data( const Data &other ) = default;
    ~Data() {
        std::cout << "Destructed: " << d << std::endl;
    }

    Data operator +( const T &other ) const {
        return this->d + other;
    }

    Data operator +( const Data &other ) const {
        return this->d + other.d;
    }

    Data & operator =( const Data &other ) {
        this->d = other.d;
        return *this;
    }

    Data & operator=( const T &t ) {
        this->d = t;
        return *this;
    }
};