简体   繁体   English

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

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

While compiling the below standard-code of overloaded ostream operator, a compilation error "error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream'} and 'Digit')" is being returned for the post-fix increment console-out case.在编译以下重载 ostream 运算符的标准代码时,出现编译错误“错误:'operator<<' 不匹配(操作数类型为 'std::ostream' {aka 'std::basic_ostream'} 和 'Digit') "正在为后修复增量控制台输出案例返回。

It is clear that making the 2nd argument "const" solves the compilation error.很明显,使第二个参数“const”解决了编译错误。 Kindly check and explain why this is happening.请检查并解释为什么会发生这种情况。

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;
}

why this is happening.为什么会这样。

Because the postfix version of overloaded operator++ returns by value which means that a call to Digit::operator++(int) is an rvalue which can't be bound to the nonconst lvalue reference parameter(named d ) of the overloaded operator<< and so the error.因为重载operator++的后缀版本按值返回,这意味着对Digit::operator++(int)的调用是一个右值,它不能绑定到重载operator<<的非常量左值引用参数(名为d )等等错误。

Basically, ++digit is an lvalue expression which can be bound to a nonconst lvalue reference while digit++ is an rvalue expression which can't be bound to a nonconst lvalue reference.基本上, ++digit是一个左值表达式,可以绑定到非常量左值引用,而digit++是一个右值表达式,不能绑定到非常量左值引用。

To solve this we have to add a low-level const to the second parameter(named d ) as shown below:为了解决这个问题,我们必须向第二个参数(名为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);

Adding a low-level const works because a const lvalue reference can be bound to an rvalue expression such as a call to Digit::operator++(int) .添加低级 const 是可行的,因为 const 左值引用可以绑定到右值表达式,例如对Digit::operator++(int)的调用。 That is, even though digit++ is still an rvalue expression, it can now be bound to the modified const lvalue reference parameter named d .也就是说,即使digit++仍然是一个右值表达式,它现在也可以绑定到名为d的修改后的 const 左值引用参数。

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

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