我想重载运算符<<,并且无法将'std::ostream {aka std::basic_ostream<char>}'左值绑定到'std::basic_ostream<char>&&”

I want to overloaded operator<<, and get cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'

提问人:Stozn 提问时间:2/20/2023 最后编辑:Stozn 更新时间:2/20/2023 访问量:139

问:

我想重载运算符<<,并得到此错误。

C:\Users\Administrator\Desktop\1.cpp    In function 'int main()':
22  18  C:\Users\Administrator\Desktop\1.cpp    [Error] cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
39  0   D:\Dev-Cpp\MinGW64\lib\gcc\x86_64-w64-mingw32\4.9.2\include\c++\iostream    In file included from D:/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/iostream
1       C:\Users\Administrator\Desktop\1.cpp                     from C:\Users\Administrator\Desktop\1.cpp
602 5   D:\Dev-Cpp\MinGW64\lib\gcc\x86_64-w64-mingw32\4.9.2\include\c++\ostream [Note] initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = OutputFormatter]'

#include <iostream>
#include <iomanip>
 
class OutputFormatter {
public:
    OutputFormatter(int width) : m_width(width) {}

    template<typename T>
    friend std::ostream& operator<<(std::ostream& os, const OutputFormatter& formatter) {
        os << std::setw(formatter.m_width);
        return os;
    }

private:
    int m_width;
};

OutputFormatter formatted_output(8); 

int main() {
    int a = 123, b = 456;
    std::cout << formatted_output << a << b << std::endl;
    return 0;
}

使用 TDM-GCC-4.9.2 和 -std=c++11 进行测试

我希望重载运算符<<,使所有输出变量的宽度为 8 个字符,但这似乎不可行。

C++ 运算符重载 IOSTREAM

评论

5赞 WhozCraig 2/20/2023
我敢问你为什么要模板化那个运算符?仅供参考,“我得到一个错误”没有帮助。“我收到错误:”,并且逐字显示错误消息的信息量要大得多。
1赞 463035818_is_not_an_ai 2/20/2023
请在问题中包含编译器错误消息。我在这里得到的很清楚出了什么问题:godbolt.org/z/4ncvPeWPa 您似乎随机选择了消息的一部分,但不是第一个错误
1赞 molbdnilo 2/20/2023
编译器不可能为(无意义的)模板参数推断类型。错误消息令人困惑,因为您的编译器真的很旧。
0赞 463035818_is_not_an_ai 2/20/2023
无论我尝试了哪个 gcc 版本,我总是收到与您在标题中报告的错误消息不同的错误消息。要么你没有向我们展示你编译的代码,要么你误读了错误消息,或者发生了其他奇怪的事情。在任何情况下,您都应该在问题中包含错误消息。如果太长,请选择第一部分。编译器的输出包含错误行、出现错误的代码以及更有价值的信息。标题中包含的片段不是很有用。
0赞 Stozn 2/20/2023
好的,谢谢你的建议,这是我第一次在那里提问。

答:

1赞 kaba 2/20/2023 #1

您不参与重载解析,因为您定义了模板参数(未使用)。因此,这将执行以下操作:operator<<

#include <iostream>
#include <iomanip>
 
class OutputFormatter {
public:
    OutputFormatter(int width) : m_width(width) {}

    friend std::ostream& operator<<(std::ostream& os, const OutputFormatter& formatter) {
        os << std::setw(formatter.m_width);
        return os;
    }

private:
    int m_width;
};

OutputFormatter formatted_output(8); 

int main() {
    int a = 123, b = 456;
    std::cout << formatted_output << a << b << std::endl;
    return 0;
}

您可以在编译器资源管理器上看到立竿见影的效果。