Reputation: 921
I am trying to learn templates and overloads at the same time. I have wrote the code below but I fail to do assignement of the data object with built-in types. What am I dooing wrong and how to solve it and yet better what is the best practice that can result in no intemediate-copy constructors to be called?
I want to have all the possible arithmetic operations. I think if I get it right for one of them (e.g. +) then others would be the same principles.
Do I need Copy/Move constructor and assignements?
#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
}
Upvotes: 1
Views: 50
Reputation: 311058
For starters you may not overload an operator just by the return type as
void operator=(const T& t) {
this->d += t;
}
Data operator=(const T& t) { // FAIL
return Data(this->d + t);
}
As for other problem then in this statement
d = c + 1;
the expression c + 1
has the return type void
due to the declaration of the operator
void operator+(const T& other) {
this->d += other;
}
The operator should be declared and defined like
Data operator +(const T& other) const
{
return this->d + other;
}
The operators can be overloaded as it is shown below
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;
}
};
Upvotes: 1
Reputation: 481
The problem is that you have defined both void operator=(const T& t)
and Data operator=(const T& t)
. C++ does not allow two functions to differ by just the return type since it is impossible to resolve which overload should be called when.
Upvotes: 1