繁体   English   中英

operator<< 重载需要 const 输入参数进行编译

[英]Overloading of operator<< requiring const input argument for compilation

在编译以下重载 ostream 运算符的标准代码时,出现编译错误“错误:'operator<<' 不匹配(操作数类型为 'std::ostream' {aka 'std::basic_ostream'} 和 'Digit') "正在为后修复增量控制台输出案例返回。

很明显,使第二个参数“const”解决了编译错误。 请检查并解释为什么会发生这种情况。

class Digit
{
private:
    int m_digit;
public:
    Digit(int digit=0)
        : m_digit{digit}
    {
    }

    Digit& operator++(); // prefix has no parameter
    Digit operator++(int); // postfix has an int parameter

    friend std::ostream& operator<< (std::ostream& out, /*const*/ Digit& d);
};

// No parameter means this is prefix operator++
Digit& Digit::operator++()
{
    // If our number is already at 9, wrap around to 0
    if (m_digit == 9)
        m_digit = 0;
    // otherwise just increment to next number
    else
        ++m_digit;

    return *this;
}

// int parameter means this is postfix operator++
Digit Digit::operator++(int)
{
    // Create a temporary variable with our current digit
    Digit temp{*this};

    // Use prefix operator to increment this digit
    ++(*this); // apply operator

    // return temporary result
    return temp; // return saved state
}


std::ostream& operator<< (std::ostream& out, /*const*/ Digit& d)   //-> works fine if const is uncommented
{
    out << d.m_digit;
    return out;
}

int main()
{
    Digit digit(5);

    std::cout << digit;
    std::cout << ++digit; // calls Digit::operator++();
    std::cout << digit++; // calls Digit::operator++(int);   //-> THIS LINE DOES NOT COMPILE
    std::cout << digit;

    return 0;
}

为什么会这样。

因为重载operator++的后缀版本按值返回,这意味着对Digit::operator++(int)的调用是一个右值,它不能绑定到重载operator<<的非常量左值引用参数(名为d )等等错误。

基本上, ++digit是一个左值表达式,可以绑定到非常量左值引用,而digit++是一个右值表达式,不能绑定到非常量左值引用。

为了解决这个问题,我们必须向第二个参数(名为d )添加一个低级 const ,如下所示:

//--------------------------------------------------vvvvv------------>adding const works because a const lvalue reference can be bound to an rvalue
friend std::ostream& operator<< (std::ostream& out, const Digit& d);

添加低级 const 是可行的,因为 const 左值引用可以绑定到右值表达式,例如对Digit::operator++(int)的调用。 也就是说,即使digit++仍然是一个右值表达式,它现在也可以绑定到名为d的修改后的 const 左值引用参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM