无法组合模板和类函数重载

时间:2016-07-05 15:08:08

标签: c++ function templates overloading operator-keyword

下面的代码工作正常,按预期打印50。然而,我不理解的是为什么同一个程序不能用这个代码稍作改动。这两行建议代码标记为错误代码1和2.当这些代码替换为它们左侧的当前工作代码时(即mainerror: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream}' and 'MyClass')| ),我收到以下错误:

addStuff(x,y)

我期望它工作的方式是:当coutmain()的(错误的)x+y行中调用时,它首先评估operator+,这是由#include <iostream> using namespace std; class MyClass { public: MyClass(){} MyClass(int a) : priV(a){} MyClass operator+(MyClass otherMC) { MyClass newMC; newMC.priV = this->priV + otherMC.priV; return newMC; } int getVar(){return priV;} void setVar(int v){priV=v;} private: int priV; }; template <class gen> gen addStuff(gen x, gen y) { return x+y; //Bad code 1: return (x+y).getVar(); } int main() { MyClass x(20), y(30); cout << addStuff(x,y).getVar() << endl; //Bad code 2: cout << addStuff(x,y) << endl; } MyClass重载的成员函数定义的。这应该只返回一个MyClass对象,然后调用getVar没有问题。

我在这里缺少什么?

{{1}}

3 个答案:

答案 0 :(得分:2)

您对第1行中应该发生的事情的解释return (x+y).getVar();是正确的。将在参数x和y上调用重载的operator+,并在getVar()的结果上调用operator+。当x和y是MyClass类型时,operator +调用返回MyClass类型的对象,因此对getVar()的调用有效。

但是,getVar()返回一个int。您的函数addStuff被指定为返回gen,这是与参数x和y匹配的相同模板参数。这意味着当x和y是MyClass时,addStuff函数必须返回MyClass。

因此,当您将addStuff(x,y)放入cout语句时,addStuff的返回类型被推断为MyClass。这就是使编译器产生“没有运算符&lt;&lt;类型MyClass”的错误的原因。

如果您希望addStuff返回getVar()的结果,则应声明它返回int,而不是gen

答案 1 :(得分:1)

您必须修改addStuff以便它返回int,而不是模板参数gen(将MyClass):

template <class gen>
int addStuff (gen x, gen y)
{
    return (x + y).getVar ();
}

如果你没有将gen更改为int,那么该函数将正常工作,因为构造函数MyClass(int a)将被显式调用,然后结果将是类型为{的对象{1}}。

显然,编译器会说你不能'MyClass'cout类型的对象。

所以我建议你用MyClass标记构造函数: 你的代码也没有编译,因为没有默认的构造函数,所以添加一个,或者只是用默认值标记参数:

explicit

修改 如果您不想在更改成员类型时更改函数的返回类型,则可以使用decltype,以使代码更通用:

explicit MyClass (int a = 0) : priV (a) {}

答案 2 :(得分:1)

问题出在addStuff函数中,它返回从int变量构造的MyClass对象。您需要修改此功能以使用“错误代码”

template <class gen>
int addStuff(gen x, gen y)
{
    return (x+y).getVar();
}

或者为MyClass编写一个ostream运算符。为此,您需要修改getVar方法,包含朋友声明并实施它

int getVar() const { return priV; }
friend std::ostream& operator<< (std::ostream &out, const MyClass& m);
std::ostream& operator<< (std::ostream& out, const MyClass& m) {
    out << m.getVar();
    return out;
}

这样您就不需要修改addStuff功能。

旁注,您的代码没有为我编译,因为MyClass中没有默认构造函数,不得不像这样修改构造函数

MyClass(int a = 0) : priV(a) {}