-1

I'm trying to make a fractionType class with functional arithmetic with objects of the same class, I'm also using a template so that the fractionType object can be constructed with an int, float, or double. I've been looking all over for solutions to one problem after another, so I'm needing help resolving the above error in this code:

main.cpp:

#include <iostream>
#include "fractionType.h"
using namespace std;

int main()
{
    fractionType<int> x(4, 2);
    fractionType<double> y(5.2, 6.8);
    fractionType<float> z(1.0, 1.0);
    z = x + y;
    return 0;
}

fractionType.h:

#ifndef FRACTIONTYPE_H
#define FRACTIONTYPE_H
using namespace std;

template <class T>
class fractionType;


template <class T>
class fractionType
{
    public:
    explicit fractionType();
    explicit fractionType<T>(T num, T den);
    T numerator;
    T denominator;
};

template <class T>
fractionType<T>::fractionType()
{
    
}

template <class T>
fractionType<T>::fractionType(T num, T den)
{
    numerator = num;
    denominator = den;
}

template <typename U, typename V>
fractionType<int> operator + (const fractionType<U>& fraction1, const fractionType<V>& fraction2)
{
    fractionType<int> tempFraction(1,1);
    tempFraction.numerator = (fraction1.numerator * fraction2.denominator + fraction1.denominator * fraction2.numerator);
    tempFraction.denominator = (fraction1.denominator * fraction2.denominator);
    return tempFraction;
}
#endif

The error:

main.cpp: In function ‘int main()’:
main.cpp:10:13: error: no match for ‘operator=’ (operand types are ‘fractionType’ and ‘fractionType’)
   10 |     z = x + y;
      |             ^
In file included from main.cpp:2:
fractionType.h:10:7: note: candidate: ‘fractionType& fractionType::operator=(const fractionType&)’
   10 | class fractionType
      |       ^~~~~~~~~~~~
fractionType.h:10:7: note:   no known conversion for argument 1 from ‘fractionType’ to ‘const fractionType&’
fractionType.h:10:7: note: candidate: ‘fractionType& fractionType::operator=(fractionType&&)’
fractionType.h:10:7: note:   no known conversion for argument 1 from ‘fractionType’ to ‘fractionType&&’

Any advice?

  • 2
    The template arguments are part of the type. `fractionType` is a distinct and separate type from `fractionType`. Those two types are not convertible to each other unless you have implemented the operators for it. And in the code you show (which doesn't really match the errors you get) you try to assign a `fractionType` value to a `fractionType` value. – Some programmer dude May 17 '23 at 00:23
  • 1
    The problem I mention above would be very clear if you looked at [the actual error messages](https://godbolt.org/z/T9r1bqbz9) created from the code you show. – Some programmer dude May 17 '23 at 00:28
  • On a totally different note: [`using namespace std;` is a bad habit](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) when doing it in source files. Doing it in a header file many of us would consider directly wrong. – Some programmer dude May 17 '23 at 00:29

1 Answers1

2

In the statement z = x + y;, the expression x + y returns a fractionType<int>, but z is a fractionType<float> instead. You have not defined a conversion to allow that assignment, hence the error.

You can either:

  1. define a copy constructor that lets you construct *this from other types of fractionType objects, eg:
template <class T>
class fractionType
{
public:
    ...
    template <typename U>
    fractionType(const fractionType<U> &src) {
        numerator = static_cast<T>(src.numerator);
        denominator = static_cast<T>(src.denominator);
    }
};
  1. define an assignment operator that lets you assign other types of fractionType objects to *this, eg:
template <class T>
class fractionType
{
public:
    ...
    template <typename U>
    fractionType<T>& operator=(const fractionType<U> &rhs) {
        numerator = static_cast<T>(rhs.numerator);
        denominator = static_cast<T>(rhs.denominator);
        return *this;
    }
};
  1. define a conversion operator that lets you convert *this to other types of fractionType objects, eg:
template <class T>
class fractionType
{
public:
    ...
    template <typename U>
    operator fractionType<U>() const { 
        return fractionType<U>(static_cast<U>(numerator), static_cast<U>(denominator));
    }
};
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770