簡體   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