简体   繁体   中英

Templates, no matching function for call to error

I've made a code which works just fine but one line. It causes me problems. On the line where it says k = Money<double>().increment (k,m); // this should've printed 6.25 k = Money<double>().increment (k,m); // this should've printed 6.25 it just doesn't work. When you comment it out and run the code... everything works just fine. What's wrong and how can I fix it?

Thank you for your help.

The error in the console says:

main.cpp:59:36: error: 'Money::increment(Money&, Money&)' no matching function for call to error main.cpp:59:36: info: candidate is:
main.cpp:41:3: info: T Money::increment(T, T) [with T = double]
main.cpp:41:3: info: no known conversion for argument 1 from 'Money' to 'double'

And well... candidate is empty too. As I said without that line everything works just perfect.

Here is the code:

#include <iostream>
using namespace std;

template <class T>
class Money {
  private:
    T dollar, cent;
  public:
    Money(T a, T b){
        dollar = a;
        cent = b;
    }

  Money(){
    dollar = 0;
    cent = 1;
  }

  Money& operator +=(const Money& v){
    dollar += v.dollar;
    cent += v.cent;
    return (*this);
  }

  Money operator +(const Money& v) const{
    Money temp(*this);
    temp += v;
    return temp;
  }

  Money& operator =(const Money& v){
    dollar = v.dollar;
    cent = v.cent;
    return (*this);
  }

  T increment(T value, T amount);
};

template <class T>
T Money<T>::increment(T value, T amount)
{
  T result = 0;
  result += value + amount;
  cout << result << " $" << endl;
  return result;
}

int main()
{
  int a = 2;
  double b = 3.45;

  Money<double> k(3,75);
  Money<double> m(2,50);

  a = Money<double>().increment (a,5); // this prints 7
  b = Money<double>().increment (b,4.5); // this prints 7.95
  k = Money<double>().increment (k,m); // this should've printed 6.25
  return 0;
}

T in the context of a Money<double> is double but you are not passing double s to Money<double>::increment() , you are passing Money<double> instances, and there is no implicit conversion available from Money<double> to double .

There are a few ways you could fix this.

  • You could create a conversion operator Money<T>::operator T() const; . This will provide an implicit conversion from Money<double> to double , and you can define what it does. The compiler will call this operator automatically on both Money<double> instances that you pass.
  • You could add an overload for Money<T>::increment(Money const &, Money const &); .
  • You could have Money<T>::increment be itself a template function.

It's not clear from your code exactly which approach you should take, but one of them will resolve this particular error.

The answer by @cdhowie already address the problem in your post.

This answer questions the semantics of the function increment .

You are using:

a = Money<double>().increment (a,5);

That's no different than

a += 5;

The Money<double>() object serves no purpose at all. It does not increment any Money object. That's why it makes no sense for it to be a member function of the class. To increment a Money object, one can thing of the following syntax:

int a = 2;
double b = 3.45;

Money<double> k(3,75);
Money<double> m(2,50);
Money<double> n(4,20);

k += a;         // Increment k.dollars by a
m += k;         // Increment m by k
m += b;         // Increment m.dollars by b
k.increment(n); // Increment k by n

Although I don't know why you would want to use k.increment(n) when you can use k += n .

Here's a revised version of your class, with a working main .

#include <iostream>
using namespace std;

template <class T>
class Money {
   private:
      T dollar, cent;
   public:

      Money(T a = {}, T b = {}) : dollar(a), cent(b) {}

      Money& operator +=(const Money& v){
         dollar += v.dollar;
         cent += v.cent;
         return (*this);
      }

      Money operator +(const Money& v) const{
         Money temp(*this);
         temp += v;
         return temp;
      }

      Money& operator =(const Money& v){
         dollar = v.dollar;
         cent = v.cent;
         return (*this);
      }

      friend std::ostream& operator<<(std::ostream& out, Money const& m)
      {
         return (out << "Dollors: " << m.dollar << ", Cents: " << m.cent);
      }

};

int main()
{
   int a = 2;
   double b = 3.45;

   Money<double> k(3,75);
   Money<double> m(2,50);
   Money<double> n(4,20);

   k += a; // Increment k.dollars by a
   m += k; // Increment m by k
   m += b; // Increment m.dollars by b
   k += n; // Increment k by n

   std::cout << m << std::endl;
   std::cout << k << std::endl;

   return 0;
}

Output:

Dollors: 10.45, Cents: 125
Dollors: 9, Cents: 95

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM