无法在 C++ 中重载流提取运算符 (>>)

Posted

技术标签:

【中文标题】无法在 C++ 中重载流提取运算符 (>>)【英文标题】:Unable to overload stream extraction operator (>>) in C++ 【发布时间】:2017-12-02 11:29:24 【问题描述】:

我目前正在尝试了解 C++ 中运算符重载的基本概念。因此,我创建了一个类wheel,它能够通过重载流提取运算符>> 从流中读取。

wheel.h

#ifndef WHEEL_H
#define WHEEL_H

#include <cassert>
#include <ostream>
#include <string>

class wheel final 
    float rimDiameter;
    int productionYear;
    std::string velocityIndex = "N/A";
    std::string manufacturer = "N/A";

public:
    wheel() = default;

    wheel(  float rimDiameter,
            int productionYear,
            std::string velocityIndex,
            std::string manufacturer
        ) : rimDiameterrimDiameter,
            productionYearproductionYear,
            velocityIndexvelocityIndex,
            manufacturermanufacturer
        

    ~wheel() = default;

    friend
    auto operator<<(std::ostream &os, const wheel &self) -> std::ostream &;

    friend
    auto operator>>(std::istream &is, wheel &self) -> std::istream &;
;

#endif

wheel.cpp

#include "wheel.h"

auto operator<<(std::ostream &os, const wheel &self) -> std::ostream & 
    return os << "   WHEEL" << std::endl
        << "   =============================" << std::endl
        << "      Rim Diameter:       " << self.rimDiameter << "\"" << std::endl
        << "      Year of Production: " << self.productionYear << std::endl
        << "      Velocity Index:     " << self.velocityIndex << std::endl
        << "      Manufacutrer:       " << self.manufacturer << std::endl;



auto operator>>(std::istream &is, wheel &self) -> std::istream & 
    char c[3];

    is >> 
        self.rimDiameter >> c[0] >> 
        self.productionYear >> c[1] >>
        self.velocityIndex >> c[2] >> 
        self.manufacturer;

    assert(c[0] == ';' && c[1] == ';' && c[2] == ';');
    return is;

ma​​in.cpp

#include <iostream>
#include "wheel.h"

int main(void) 
    wheel w;

    std::cin >> w;
    std::cout << w;

    return 0;

对我来说,一切看起来都很好,但不知何故,我一直收到一个错误消息,告诉我有 no match for 'operator&gt;&gt;' (operand types are 'std::istream aka std::basic_istream&lt;char&gt;' and 'float')

$ make
g++-7 -g -std=c++17 -Wall -Wextra -Wconversion -Wpedantic -c main.cpp
g++-7 -g -std=c++17 -Wall -Wextra -Wconversion -Wpedantic -c wheel.cpp
wheel.cpp: In function 'std::istream& operator>>(std::istream&, wheel&)':
wheel.cpp:16:8: error: no match for 'operator>>' (operand types are 'std::istream aka std::basic_istream<char>' and 'float')
     is >>
     ~~~^~
         self.rimDiameter >> c[0] >>
         ~~~~~~~~~~~~~~~~
wheel.cpp:13:6: note: candidate: std::istream& operator>>(std::istream&, wheel&)
 auto operator>>(std::istream &is, wheel &self) -> std::istream & 
      ^~~~~~~~
wheel.cpp:13:6: note:   no known conversion for argument 2 from 'float' to 'wheel&'
In file included from /usr/local/Cellar/gcc/7.2.0/include/c++/7.2.0/string:53:0,
                 from /usr/local/Cellar/gcc/7.2.0/include/c++/7.2.0/bits/locale_classes.h:40,
                 from /usr/local/Cellar/gcc/7.2.0/include/c++/7.2.0/bits/ios_base.h:41,
                 from /usr/local/Cellar/gcc/7.2.0/include/c++/7.2.0/ios:42,
                 from /usr/local/Cellar/gcc/7.2.0/include/c++/7.2.0/ostream:38,
                 from wheel.h:5,
                 from wheel.cpp:1:
/usr/local/Cellar/gcc/7.2.0/include/c++/7.2.0/bits/basic_string.tcc:1465:5: note: candidate: template<class _CharT, class _Traits, class _Alloc> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&)
     operator>>(basic_istream<_CharT, _Traits>& __in,
     ^~~~~~~~
/usr/local/Cellar/gcc/7.2.0/include/c++/7.2.0/bits/basic_string.tcc:1465:5: note:   template argument deduction/substitution failed:
wheel.cpp:17:14: note:   mismatched types 'std::__cxx11::basic_string<_CharT, _Traits, _Alloc>' and 'float'
         self.rimDiameter >> c[0] >>
              ^~~~~~~~~~~
make: *** [wheel.o] Error 1

我在这里错过了什么?

【问题讨论】:

你在哪里包含了 istream? @Ext3h 无处可去,这就是问题所在。非常感谢您指出这一点:) 【参考方案1】:

您需要像 #include &lt;iostream&gt; 这样为输入和输出包括 iostream,这样您就可以避免该错误。

输出时,它是定义 > 的情况。


#ifndef WHEEL_H
#define WHEEL_H

#include <cassert>
#include <iostream>
#include <string>

class wheel final 
    float rimDiameter;
    int productionYear;
    std::string velocityIndex = "N/A";
    std::string manufacturer = "N/A";

public:
    wheel() = default;

    wheel(  float rimDiameter,
          int productionYear,
          std::string velocityIndex,
          std::string manufacturer
          ) : rimDiameterrimDiameter,
    productionYearproductionYear,
    velocityIndexvelocityIndex,
    manufacturermanufacturer
    

    ~wheel() = default;

    friend
    auto operator<<(std::ostream &os, const wheel &self) -> std::ostream &;

    friend
    auto operator >> (std::istream &is, wheel &self) -> std::istream &;
;

#endif /* wheel_hpp */

【讨论】:

【参考方案2】:

正如@Ext3h 指出的那样,我缺少istream 的相应包含。

#include &lt;istream&gt; 添加到wheel.h 可以解决问题。

非常感谢你的帮助,我会花很长时间来解决这个问题!

【讨论】:

以上是关于无法在 C++ 中重载流提取运算符 (>>)的主要内容,如果未能解决你的问题,请参考以下文章

C++重载IO输入输出流运算符

C++重载IO输入输出流运算符

C++重载IO输入输出流运算符

C++重载IO输入输出流运算符

C++重载IO输入输出流运算符

C++重载IO输入输出流运算符