g++ 编译器为表达式提供 << 类型错误,但在 Visual Studio 中有效

g++ compiler giving << type errors for expressions, but works in Visual Studio

好的,我认为这可能只是版本问题,但我是新手。我有一个主文件,它使用我覆盖的 << 运算符作为 BigInt class 我已经实现:

BigInt a = 3;
cout << a << endl;
cout << (a+a) << endl;

在 Visual Studio 中,编译器可以很好地理解所有内容,而且 运行 很棒。但是转到 Ubuntu 14.04,make 使用我的 Makefile(它使用普通 g++ 命令)给了我由 第三行 (以及任何其他使用带有表达式的 cout 的行)。如果我删除第三行,它编译得很好。第一个错误是:

main.cpp:23:8: error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'BigInt')
    cout << (a+a);
         ^

这令人困惑,因为我的 << 运算符函数采用引用参数:

// in BigInt.h, in class' public section:

BigInt operator+(BigInt const& other) const;
friend std::ostream & operator<<(std::ostream& os, BigInt& num);


// in BigInt.cpp:

BigInt BigInt::operator+(BigInt const& other) const {
    // call appropriate helper based on signs
    if (this->neg == other.neg) {
        return sum(other);
    }
    else {
        return difference(other);
    }
}

ostream & operator<<(ostream& os, BigInt& num) {
    if (num.dataLength == -1) {
        os << "**UNDEFINED**";
    }
    else {
        if (num.neg) os << "-";
        if (num.dataLength == 0) {
            os << "INFINITY";
        }
        else {
            // print each digit
            for (int i = num.dataLength - 1; i >= 0; i--) {
                os << (short)num.data[i];
            }
        }
    }
    return os;
}

那么为什么第一个 cout 有效而第二个 cout 无效?有没有办法 运行 g++ 这样它可以工作?

ostream & operator<<(ostream& os, BigInt& num)

应该拿一个BigInt const& numMSVC is non-compliant with regards to this。 g++ 没有这个扩展。

确保更改 header 文件中的声明和 BigInt.c 文件中的定义。 (此外,包含 C 代码的文件通常使用 .c,包含 C++ 代码的文件使用 .cpp。)

原因是 (a+a) 创建了一个 临时 BigInt,不能绑定到非 const 引用。第一个 cout 起作用是因为 a 是局部变量,而不是临时变量,因此可以作为普通(非 const)引用传递。

除了临时文件的问题之外,应用 const-correctness 是一个很好的做法:除非您确实需要更改它们,否则请制作东西 const。这有助于防止错误。请注意,std::ostream& os 不能是 const,您确实可以通过写入来更改它。

问题在于

friend std::ostream & operator<<(std::ostream& os, BigInt& num);

因为你使用 BigInt& num 这将不适用于 (a+a) 因为它会创建一个临时文件并且你不能引用临时文件。它适用于 MSVS as they have an extension to allow this 但 g++ 不适用。将其更改为

friend std::ostream & operator<<(std::ostream& os, const BigInt& num);

So why does the first cout work but not the second?

您的 operator << 通过非常量引用获取第二个参数。 (a+a) 之类的临时变量无法绑定到它,因此第二次调用是非法的。 MSVC 允许将其作为扩展,但它不是标准的 C++。

Is there a way to run g++ such that it can work?

没有。修复您的运算符以改用 const 引用。