【问题标题】:Why the code doesn't work on CodeBlocks,but on VS works为什么代码在 CodeBlocks 上不起作用,但在 VS 上起作用
【发布时间】:2019-05-10 10:04:50
【问题描述】:

这一行: “朋友 ostream& 运算符expected ',' or '...' before '&&' token|”

#include <iostream>
#include <cstdio>
using namespace std;
int lcf(int n, int m)
{
    if (n < m)
    {
        int tmp = n;
        n = m;
        m = tmp;
    }
    if (n % m == 0)
        return m;
    else
        return lcf(m, n % m);
}
class Fraction
{
private:
    int fenzi, fenmu;
public:
    Fraction(int a, int b) :fenzi(a), fenmu(b) {}
    Fraction operator+(Fraction& another)
    {
        fenzi += another.fenzi;
        fenmu += another.fenmu;
        return *this;
    }
    Fraction operator*(Fraction& another)
    {
        fenzi *= another.fenzi;
        fenmu *= another.fenmu;
        return *this;
    }
    operator double()
    {
        return 1.0* fenzi / fenmu;
    }
    friend istream& operator>>(istream& is, Fraction& obj)
    {
        is >> obj.fenzi;
        getchar();
        is >> obj.fenmu;
        return is;
    }
    friend ostream& operator<<(ostream& os, Fraction&& obj)
    {
        int t = lcf(obj.fenzi, obj.fenmu);
        obj.fenzi /= t;
        obj.fenmu /= t;
        os << obj.fenzi << "/" << obj.fenmu;
        return os;
    }
    Fraction& operator++()
    {
        fenzi++;
        fenmu++;
        return *this;
    }
    Fraction operator++(int)
    {
        Fraction tmp(fenzi, fenmu);
        fenzi++;
        fenmu++;
        return tmp;
    }
};
int main()
{
    Fraction a1(9, 11), a2(1, 2);
    cout << double(a2) << endl;
    cout << ++a1 << endl;
    cout << a2++ << endl;
    cout << a1 * a2 << endl;
    return 0;
}

如果代码是: "friend ostream& 运算符" 在主函数中,“cout ”会奇怪地调用“operator double()”函数而不是“friend ostream& operator

【问题讨论】:

  • &amp;&amp; 是必需的,因为 a1*a2 返回无法绑定到非常量引用的 r 值。它可以绑定到const T&amp;,这将解决问题,但您的运算符需要非常量。请重新考虑在印刷品内有副作用,这是出乎意料和危险的。确保 CodeBlocks 设置为 c++11 或更高版本。也与&amp;&amp; cout&lt;&lt;++a1 不应该工作。

标签: c++


【解决方案1】:
cout << ++a1 << endl;//(1)
cout << a2++ << endl;//(2)
cout << a1 * a2 << endl;//(3)
  1. 结果为@​​987654322@,因此它可以绑定到Fraction&amp;const Fraction&amp;,但不能绑定到Fraction&amp;&amp;。编译器允许进行一次隐式的用户定义转换,因此作为编译代码的最后一次尝试,它将转换为 double 并使用 operator&lt;&lt;(ostream&amp;,double&amp;&amp;)operator&lt;&lt;(ostream&amp;,double) 不确定哪个已定义但输出相同。
  2. cout &lt;&lt; a2++ &lt;&lt; endl; 结果为 Fraction,因此它可以绑定到 Fraction&amp;&amp;const Fraction&amp; 但不能绑定到 Fraction&amp;operator&lt;&lt;(ostream&amp;,Fraction&amp;&amp;) 被调用。
  3. cout &lt;&lt; a1 * a2 &lt;&lt; endl; 结果为 Fraction 与之前相同。

您应该几乎永远不会有副作用的打印。当然不是那些修改你传递的对象的。然后有人会编写这样的代码,而可怜的灵魂会在调试器上花费不必要的时间:

Fraction a;
Fraction b = a;
if(debug_build)
  cout <<"LOG:"<<a<<'\n';
assert(a==b);

我的解决方案是:

friend ostream& operator<<(ostream& os, const Fraction& obj)
{
    int t = lcf(obj.fenzi, obj.fenmu);
    os << obj.fenzi/t << "/" << obj.fenmu/t;
    return os;
}

Eveything 可以绑定到const Fraction&amp;,它应该是const。 (1),(2),(3) 将起作用,没有人会调用double()。我什至会考虑让double() 明确,因为它会禁止这些让你感到困惑的意外调用。除非您有充分的理由不这样做,否则一些额外的输入可能不符合条件。 最后一件事是真正鼓励您保持 const 正确,不要进行不必要的复制。

  • Fraction&amp; operator+(const Fraction&amp; another)
  • Fraction&amp; operator+(const Fraction&amp; another)
  • Fraction operator++(int) const

不确定 g 代码块 中发生了什么错误,因为您没有发布错误消息。我猜 你必须启用 c++11。

【讨论】:

  • 贴出错误信息;你的结论是正确的
  • @LightnessRacesinOrbit 谢谢,没有注意到代码 sn-p 上方的编辑。
  • 哦,好吧,我的错:D
猜你喜欢
  • 1970-01-01
  • 2014-07-18
  • 2021-02-10
  • 2021-11-15
  • 1970-01-01
  • 1970-01-01
  • 2015-04-17
  • 2021-01-07
  • 2013-06-18
相关资源
最近更新 更多