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
}
CodePudding user response:
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;
}
};
CodePudding user response:
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.