【问题标题】:Templates, no matching function for call to error模板,没有匹配的函数调用错误
【发布时间】:2017-09-26 22:53:24
【问题描述】:

我编写了一个代码,它工作得很好,但只有一行。它给我带来了问题。在上面写着k = Money<double>().increment (k,m); // this should've printed 6.25 的那一行,它根本不起作用。当您将其注释掉并运行代码时……一切正常。出了什么问题,我该如何解决?

感谢您的帮助。

控制台中的错误提示:

main.cpp:59:36: error: 'Money::increment(Money&, Money&)' 没有匹配函数调用错误 main.cpp:59:36:信息:候选人是:
main.cpp:41:3: info: T Money::increment(T, T) [with T = double]
main.cpp:41:3: info: 没有已知的参数 1 从 'Money' 到 'double' 的转换

嗯……候选人也是空的。 正如我所说,如果没有这条线,一切都会完美无缺。

代码如下:

#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;
}

【问题讨论】:

  • 与问题无关,但我不确定将钱作为double 美元数 double 美分数是个好主意。这似乎是两全其美。
  • 所以increment 只不过是您已经拥有的东西 - +。我看不出它的目的。做printMoney(a + 5) 也很容易,它不会隐藏输出(而且FWIW,有一个标准的std::put_money 来格式化货币,所以即使printMoney 也是不必要的)。您还需要一个 Money 对象才能使用 increment,尽管您甚至没有使用该对象。

标签: c++ function templates operators


【解决方案1】:

TMoney&lt;double&gt; 的上下文中是double,但您没有将doubles 传递给Money&lt;double&gt;::increment(),您正在传递Money&lt;double&gt; 实例,并且没有来自@987654328 的隐式转换@到double

有几种方法可以解决这个问题。

  • 您可以创建一个转换运算符Money&lt;T&gt;::operator T() const;。这将提供从Money&lt;double&gt;double 的隐式转换,您可以定义它的作用。编译器将在您传递的两个 Money&lt;double&gt; 实例上自动调用此运算符。
  • 您可以为Money&lt;T&gt;::increment(Money const &amp;, Money const &amp;); 添加重载。
  • 您可以将 Money&lt;T&gt;::increment 本身作为模板函数。

从您的代码中并不清楚您应该采用哪种方法,但其中一种方法可以解决此特定错误。

【讨论】:

  • 我对 C++ 比较陌生,老实说不知道如何应用第一个。我很确定这将解决问题。你有空教我怎么做吗?
  • @TKD。将运算符的定义添加到类定义中:operator T() const { /* return a value of type T from here */ }。您需要返回的确切值由您自己弄清楚,但这是基本模板。因此对于Money&lt;double&gt;,此运算符将提供到double 的隐式转换。 Further reading
【解决方案2】:

The answer by @cdhowie 已经在您的帖子中解决了问题。

这个答案质疑函数increment的语义。

您正在使用:

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

这和

没有什么不同
a += 5;

Money&lt;double&gt;() 对象根本没有任何作用。它不会增加任何Money 对象。这就是为什么它成为类的成员函数没有意义。要增加 Money 对象,可以使用以下语法:

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

虽然我不知道你为什么要使用k.increment(n),而你可以使用k += n

这是您的课程的修订版,带有有效的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;
}

输出:

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

【讨论】:

  • 谢谢!我非常感谢您的帮助,但有一个小问题。这样我也可以让它工作。我想让它像a = increment (a,5); 一样工作,它应该抓住 a 并将其添加到 5。这就是我被卡住的地方,或者不是。我坚持的地方是k = increment(k,m);,正是这部分,因为我无法从他们那里获得价值。
  • @TKD。他的观点是a = increment(a, 5); 更好,更惯用地表示为a += 5;,这就是operator+= 的目的。
猜你喜欢
  • 1970-01-01
  • 2013-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-05
  • 2011-03-03
相关资源
最近更新 更多