代码之家  ›  专栏  ›  技术社区  ›  vestlen

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

  •  4
  • vestlen  · 技术社区  · 9 年前

    好吧,我认为这可能只是一个版本问题,但我对这一点很陌生。我有一个使用重写的主文件 << 操作员 BigInt 我实现的类:

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

    在VisualStudio中,编译器可以很好地理解一切,并且运行良好。但是转到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起作用,而第二个却不起作用呢?有跑步的方法吗 克++ 这样它就可以工作了?

    3 回复  |  直到 9 年前
        1
  •  13
  •   Community Dan Abramov    7 年前
    ostream & operator<<(ostream& os, BigInt& num)
    

    应该采取 BigInt const& num . MSVC is non-compliant with regards to this .g++没有此扩展名。

    请确保同时更改标头中的声明和 BigInt.c 文件(此外,使用是正常的 .c 对于包含 C 代码,以及 .cpp 对于包含 C++ 代码。)

    原因是 (a+a) 创建一个 短暂的 BigInt ,不能绑定到非- const 参考第一个 cout 工作的原因是 a 是局部变量,不是临时变量,因此可以作为普通(非- 常量 )参考。

    除了临时性的问题外,应用 const -correctness :创造事物 常量 除非你真的需要改变它们。这有助于防止错误。请注意 std::ostream& os 不能是 常量 ,你真的可以通过写信来改变它。

        2
  •  6
  •   Community Dan Abramov    7 年前

    问题在于

    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);
    
        3
  •  6
  •   Baum mit Augen    9 年前

    那么,为什么第一个cout起作用,而第二个却不起作用呢?

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

    有没有一种运行g++的方法可以让它工作?

    否。请修复运算符以使用常量引用。