C++ Automatic constructor call on template operator overload? - c++

I have the following in my header file:
template<typename T>
class rational {
private:
T num;
T denom;
T gcd(T x, T y);
public:
rational(T num, T denom);
rational(T wholeNumber);
template<typename U>
friend inline rational<U> operator *(const rational<U> &lhs, const rational<U> &rhs);
}
template<typename T>
rational<T>::rational(T whole) {
this->num = whole;
this->denom = 1;
}
template<typename T>
rational<T> operator *(const rational<T> &lhs, const rational<T> &rhs) {
return rational<T>(lhs.num * rhs.num, lhs.denom * rhs.denom);
}
And the following in my main:
rational<int> x(6), y(2);
rational<int> product = y * x; // this works
rational<int> product2 = 2 * x; // this doesn't
The first product works, but the second one gives me "error: no match for ‘operator*’ in ‘2 * x’". Why? Since there is a constructor available that takes only the 2 as an argument, shouldn't that be automatically called? If not, how else would I overload the operator to have both of these work?
Thanks.

I'm not sure why the compiler will not invoke the single-argument constructor implicitly on 2 in order to produce a rational, but my guess is that the inference mechanism is simply broken when templates are involved.
One workaround (if no one knows how to fix the implicit constructor issue) is to define an additional multiply operators like thus:
template<typename T>
rational<T> operator *(const T &lhs, const rational<T> &rhs) {
return rational<T>(lhs * rhs.num, rhs.denom);
}
template<typename T>
rational<T> operator *(const rational<T> &lhs, const T &rhs) {
return rational<T>(lhs.num * rhs, lhs.denom);
}
This will also perform better, if you are writing high-performance code using rationals in an inner loop somewhere.

2 * x;
is analogical equivalent to calling of,
int::operator*(const rantional<int>&)
2 is an int and it doesn't have operator * overloaded for const rational<int>&; thus you get compiler errors.
The correct way is to have:
rational<int> product2 = rational<int>(2) * x; // ok

Related

operator overloading using template

I'm writing a class named Double which extends the built in type 'double' in c++. It has a data member of the type 'double'. For the class Double I need to overload many basic arithmetic operators like "+", "-", "*", "/". For example, the "+" operator is overloaded this way:
Relation<Double>* operator+ (Double &d2)
// Relation is a abstract class template.
{
/*
...code that do something else.
*/
return new Plus<Double>(this, &d2); // Plus is derived from Relation.
}
// Double + Double returns a Relation pointer.
and the "-" operator is overloaded fast the same way:
Relation<Double>* operator- (Double &d2)
{
/*
...code that do something else but the same as above.
*/
return new Minus<Double>(this, &d2);
}
The actual calculation is done by the member function in the Relation class. The only difference of the operators' bodies is the object initialized(Plus vs Minus).
For operator that takes exactly two operands, I should alway do the overloading like this, which is duplicated and not nice.
So template function comes to my mind. But the problem is, I can pass Plus or Minus as template argument, but can not pass the operator. How could I make a template or use other methods to do the overloading of these operators?
Yes, operator overloading may be a pain and source of code duplication, see this suggestion to the standard to ease it.
For now the only I can think about is something like this:
template<typename T>
struct OperatorMinus {
static T doIt(T const& lhs, T const& rhs) { return lhs - rhs; };
}
template<typename T>
struct OperatorPlus {
static T doIt(T const& lhs, T const& rhs) { return lhs + rhs; };
}
template<typename T, typename U>
class Operator: public Relation<T>
public:
Operator(T const& lhs, T const& rhs): _lhs(lhs), _rhs(rhs) {}
T doIt() override {
return U::doIt(_lhs, _rhs);
}
private:
T _lhs;
T _rhs;
};
Relation<Double>* operator+ (Double &d2)
{
return new Operator<Double, OperatorPlus<Double>>(this, &d2);
}

Any way to define a "doubling" operator?

I have a class that represents a quantity that can only take on integer or half-integer values, and so stores its value internally as an integer that is twice the value. That is: a value of 0.5 is stored as 1, 1 as 2, 1.5 as 3, etc. Let's call it class A with a stored value int TwoA_.
This forces the A values to be properly integer or half-integer. Since I often need to use them as their true values, I have naturally made a cast to double operator that simply returns 0.5 * TwoA_.
However, very frequently I need to use twice the value. I thought it would be neat to code 2 * a (a being an object of type A) to directly return the value TwoA_ stored inside a.
Ideally, I'd like to make an operator that only does this when multiplied by 2 from the left. All other situations would be covered by the implicit cast.
Is there any way to do this in c++? I though of some sort of templated multiplication operator.
The simple solution of just defining
friend double operator*(int lhs, const A& rhs)
{ return (lhs == 2) ? rhs.TwoA_ : lhs * static_cast<double>(rhs); }
is not what I'm looking for. 2 * a is guaranteed to be an int (but generically an_int * a is not), and I would like to return an int.
This is a question of curiosity; if you only want to comment "why would you want to do that?" (or some variation thereof), please hold your tongue.
An edit: I meant multiplication on the left by the integer literal 2 (not an integer variable which is tested to see if it has the value 2)
Understanding your question to be if you can overload the * operator such that it returns a different data type based on the value of one of the parameters, the short answer is: No.
The long answer: No, but maybe yes.
double operator*(const int lhs, const A& rhs);
That operator would have to know AT COMPILE TIME if lhs is 2 or not, and that cannot be guaranteed. Which means a decision as to how to handle the case of lhs being 2 or not must be done at runtime. But the data type that an operator returns must be known at compile time...
double operator*(const some_type_1& lhs, const A& rhs);
int operator*(const some_type_2& lhs, const A& rhs);
This would get you two different return types, but only with compile-time knowledge of what those argument types are.
template<int T>
struct special_number{};
//...
template<>
int operator*(const special_number<2>&, const A& rhs){
return rhs.TwoA_;
}
template<int T>
double operator*(const special_number<T>&, const A& rhs){
return (static_cast<double>(rhs) / 2.0) * T;
}
//usage
int answer1 = special_number<2> * my_a_object;
double answer2 = special_number<3> * my_a_object;
This would do just that.
struct two_t {
constexpr two_t() {};
template<class T>
constexpr operator T()const{return 2;}
};
constexpr two_t two;
Now:
friend double operator*(two_t lhs, const A& rhs)
{ return rhs.TwoA_; }
friend double operator*(const A& lhs, two_t lhs)
{ return lhs.TwoA_; }
is about the best you can do.
The type of an expression is not dependent on the values, except in the special case where the constant 0 can be converted to a pointer and can cause different overload resolutions.
That special case cannot be leveraged to make 2 special when passed as an argment to *.
Now
constexpr std::ptrdiff_t from_digits(std::integer_sequence<char>) {
return 0;
}
constexpr std::ptrdiff_t compile_time_pow( std::ptrdiff_t base, std::size_t exp ) {
return exp ? base * compile_time_pow( base, exp-1 ) : std::ptrdiff_t(1);
}
template<char c0, char...cs>
constexpr std::ptrdiff_t from_digits(std::integer_sequence<char, c0, cs...>) {
return
compile_time_pow(10, sizeof...(cs))*(c0-'0')
+ from_digits( std::integer_sequence<char, cs...>{} );
}
template<char...cs>
constexpr auto operator"" _integer() {
return std::integral_constant<std::ptrdiff_t, from_digits( std::integer_sequence<char, cs...>{} )>{};
}
Now 2_integer is a compile_time std::ptrdiff_t of value 2, with the value encoded in its type.
Thus 2_integer * a could be overridden to return a differnet type than 3_integer * a, or 2 * a.

Overloading operators in C++ with template classes

I have the following template class:
template <class T>
class Matrix {
public:
Matrix(size_t rows, size_t columns, const T elements = 0);
// scalar multiplication
Matrix<T> operator*(const T& rhs){
Matrix<T> result(rows, columns);
for(size_t index = 0; index < rows * columns; ++index){
result.elements[index] = elements[index] * rhs;
}
return result;
}
Matrix <T> operator*(const T& lhs, const Matrix<T>& rhs);
const size_t rows;
const size_t columns;
private:
std::vector<T> elements;
};
and the following implementation of the operator* :
// scalar multiplication
template <class T>
Matrix<T> Matrix<T>::operator*(const T& lhs, const Matrix<T>& rhs){
Matrix<T> result(rhs.rows, rhs.columns);
for(size_t index = 0; index < rhs.rows * rhs.columns; ++index){
result.elements[index] = elements[index] * lhs;
}
return result;
}
when I try to compile clang says: error: overloaded 'operator*' must be a unary or binary operator (has 3 parameters)|
And I don't quite understand, what I am missing in this. In general template classes give me a hard time when it comes to overloading operators and I don't know why. There have been some posts on here on SO on this topic and I tried a few variations of the code but none of them worked.
The simple and reasonably efficient way to solve this problem is as follows:
Implement Matrix& operator *=(SomeType const&) and similar operations first. These are mutating operations that change an instance of the class, then return a reference to *this.
Implement other operations as inline friends in terms of *=, where the lhs (usually) argument is taken by-value, modified and returned.
This tends to be really simple and quite often more efficient than starting with operator* instead of operator*=.
So you'll have:
template<class T, etc>
struct Matrix{
Matrix& operator*=(T const&);
Matrix& operator*=(Matrix const&);
Matrix& operator+=(Matrix const&);
which you implement traditionally. Then:
friend Matrix operator*(T const& t, Matrix m){ m*=t; return m; }
friend Matrix operator*(Matrix m, T const& t){ m*=t; return m; }
friend Matrix operator*(Matrix lhs, Matrix const& rhs){ lhs*=rhs; return lhs; }
friend Matrix operator+(Matrix lhs, Matrix const& rhs){ lhs+=rhs; return lhs; }
and now you only need to implement a few, traditional, methods.
These friend operators are non-template inline non-method functions that are auto-generated for each template instance of Matrix.
Your immediate problem was your non-static operator actually took an implicit this in addition to its two explicit parameters, and binary operators cannot take 3 arguments.
The complex and even more efficient solution involves a technique often called "expression templates". The disadvantage is that expression templates are more complex to write, and have a few points of fragility around the auto keyword and similar situations.
As an example:
Matrix m = m1 * m2 + m3 * m4 + m5 + m6;
An expression template will do the above with only one allocation of the internal data of a matrix.
My above code will copy m1, multiply the result by m2. Then it will copy m3, then multiply that by m4. Then it will add up everything without making any additional copies. Finally, this result will be moved into m.
So two matrices will be created instead of 1 in the expression template case.
A more-naive solution (like the OP's design) would create 5 Matrices instead of 2.
You're declaring Matrix <T> operator*(const T& lhs, const Matrix<T>& rhs); as member function, which has an implicit parameter this, that why compiler complains it "has 3 parameters".
You can make it a free template function,
template <class T>
class Matrix {
...
template <class Z>
friend Matrix<Z> operator*(const Z& lhs, const Matrix<Z>& rhs);
...
};
and
// scalar multiplication
template <class Z>
Matrix<Z> operator*(const Z& lhs, const Matrix<Z>& rhs){
Matrix<Z> result(rhs.rows, rhs.columns);
for(size_t index = 0; index < rhs.rows * rhs.columns; ++index){
result.elements[index] = elements[index] * lhs;
}
return result;
}
Your function is a member function. Member functions have a hidden parameter, the this pointer.
You either need to make your operator* a non-member function or you need to get rid of one of the arguments to your operator* function (which will then multiply the data in "this" with the data in the incoming Matrix<T>.)

template operators fail seemingly on ambiguity

This is not a duplicate. I've checked lots of answers, the FAQ and else. Nothing of that told me news. Here is the simplified code. It's the minimum to get and explain the error.
/*** Polynomial.hpp ********************************************************/
namespace Modulus
{
// Forward declaration of the types and non-inline template friend functions.
template <typename T>
class Polynomial;
template <typename T>
Polynomial<T> operator +
(Polynomial<T> const & p,
Polynomial<T> const & q);
}
namespace Modulus
{
template <typename T>
class Polynomial
{
public:
Polynomial() { }
// [!] when you comment this in, you get the error.
//Polynomial operator + () const { return *this; }
friend Polynomial operator + <> (Polynomial const & p,
Polynomial const & q);
};
} // namespace
// Template: include .cpp file.
//#include "Polynomial.cpp"
///^ It is commented out, for compiling in one file.
/*** Polynomial.cpp ********************************************************/
namespace Modulus
{
template <typename T>
Polynomial<T>
operator + (Polynomial<T> const & p,
Polynomial<T> const & q)
{
return Polynomial<T>();
}
} // namespace
/*** main.cpp **************************************************************/
//#include "Polynomial.hpp"
using namespace Modulus;
int main()
{
Polynomial<int> p;
p + p;
return 0;
}
When I comment the line under [!] in, the error I get is friends can only be classes or functions (Clang++) or declaration of ‘operator+’ as non-function (g++).
For me, it seems the compilers mistake the two operators. As far as I've learned the operator overloading stuff, the unary and binary operators are completely independent and can be uniquely distinguished by their number of arguments.
So why does the error occur? Making the unary operator a friend using the standard practice, makes the code compile fine on both compilers.
When you declare something in a scope, it hides delcarations of the same name in any wider scope. Here, the declaration of the member operator+ hides that of the non-member. So the friend declaration refers to the member, not the non-member, hence the error.
You'll need to qualify the name if you want to refer to both in the same scope:
Polynomial operator + () const { return *this; }
friend Polynomial Modulus::operator + <> (Polynomial const & p, Polynomial const & q);
^^^^^^^^^

Multiplying an object with a constant from left side

I have a Matrix class and it has overloaded * operators for scalar and matrix multiplications.
template <class T> class Matrix
{
public:
// ...
Matrix operator*(T scalar) const;
// ...
}
// ...
template <class T>
Matrix<T> Matrix<T>::operator*(T RightScalar) const
{
Matrix<T> ResultMatrix(m_unRowSize, m_unColSize);
for (uint64_t i=0; i<m_unRowSize; i++)
{
for (uint64_t j=0; j<m_unColSize; j++)
{
ResultMatrix(i, j) = TheMatrix[m_unColSize * i + j] * RightScalar;
}
}
return ResultMatrix;
}
// ...
I can multiply a matrix object with a scalar from right side without any problem:
Matrix<double> X(3, 3, /* ... */); // Define a 3x3 matrix and initialize its contents
Matrix<double> Y; // Define an output matrix
Y = X * 10.0; // Do the linear operation
But, how do I multiply it from left side same way?
Matrix<double> X(3, 3, /* ... */);
Matrix<double> Y;
Y = 10.0 * X;
In arithmetic, it is a common notation to write constants on the left side when doing multiplication. I would like to obey this rule to make my code more readable.
Is it possible to implement this in C++?
If it is possible, how do I modify the class method in my code?
Member functions are matched by their left-hand-side argument which is the this-pointer. Since native types can't have member functions, you have to add right-multiplication with user-defined types through non-member functions (and also for other types you don't have write-access to).
template<typename T>
Matrix<T> operator*(T const& scalar, Matrix<T> rhs)
{
// scalar multiplication is commutative: s M = M s
return rhs *= scalar; // calls rhs.operator*=(scalar);
}
NOTE: I wrote the above non-member operator* implemented in terms of a member operator*=. It is recommended to write all multiplications as non-member functions, and use a member operator*= to implement these multiplications with a lhs Matrix element.
This will a) keep the class interface minimal, and b) prevent hidden conversions. E.g. you could have a Matrix class that is implicitly convertible to scalar if the dimensions are 1x1, and these conversions could silently happen if you don't provide a separate overload that is a direct match.
template<typename T>
Matrix<T> operator*(Matrix<T> lhs, T const& scalar)
{
return lhs *= scalar; // calls lhs.operator*=(scalar);
}
template<typename T>
Matrix<T> operator*(Matrix<T> lhs, Matrix<T> const& rhs)
{
return lhs *= rhs; // calls lhs.operator*=(rhs);
}
Notice on how the lhs Matrix is a copy and not a reference. This allows the compiler to make optimizations such as copy elision / move semantics. Also note that the return type of these operators is Matrix<T> and not const Matrix<T> which was recommended in some old C++ books, but which prevents move semantics in C++11.
// class member
template<typename T>
Matrix<T>& Matrix<T>::operator*=(Matrix<T> const& rhs)
{
// your implementation
return *this;
}
// class member
template<typename T>
Matrix<T>& Matrix<T>::operator*=(T const& scalar)
{
// your implementation
return *this;
}
You'll need a non-member function for that:
template <typename T>
Matrix<T> operator*(T scalar, Matrix<T> const & matrix) {
return matrix * scalar;
}
Non-member operator overloads allow you to specify any type on either side, while member overloads always get the object on the left-hand side.