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