没有运算符“>".与这些操作数匹配的操作数类型为:std :: istream>>双倍的 [英] No operator ">>" matches these operands operand types are: std::istream >> double

查看:139
本文介绍了没有运算符“>".与这些操作数匹配的操作数类型为:std :: istream>>双倍的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我的项目,我正在尝试为复数类创建一个免费函数.它在cpp文件中定义.该函数是重载的输入流运算符,但我不断收到错误消息

For my project I'm trying to create a free function for a complex number class. It is defined in the cpp file. The function is an overloaded input streaming operator but I keep getting the error

No operator ">>" matches these operands operand types are: std::istream >> double

在线

in >> z.real();
in >> z.imag();

我制作了一个名为 complex.h 的文件,其中包含 complex 类和两个我想工作的重载运算符,即复数的构造函数(不确定是否需要,但是(包括),以及两个getter方法来检索复杂类的实部和虚部.重现该错误.

I made a file called complex.h that contains the complex class and the two overloaded operators I want to work, constructors for complex numbers (not sure if needed but included), and two getter methods to retrieve the real and imaginary parts of the complex class. This reproduces the error.

成员函数的声明由我的项目规范规定.它们的返回类型无法更改.

The declarations of the member functions are dictated by my project spec. Their return types cannot be changed.

#pragma once
#include <iostream>
#include <cmath>

class complex {

private://may include private helper functions
    double realX = 0;
    double imaginaryY = 0;

public:// interface for operators and member functions (methods)
    //**********************Constructors***************************
    complex() {}
    complex(double x) {
        realX = x;
    }
    complex(double x, double y) {
        realX = x;
        imaginaryY = y;
    }
    complex(const complex& z) : realX(z.realX), imaginaryY(z.imaginaryY) { //copy constructor
    }
    double real() const {
        return realX;
    }
    double imag() const {
        return imaginaryY;
    }
};

std::istream& operator>>(std::istream& in, complex& z) {
    in >> z.real();
    in >> z.imag();
    return in;
}
std::ostream& operator<<(std::ostream& output, const complex& z) {
    output << "(" << z.real()
        << ", " << z.imag()
        << "i)";
    return output;
}

推荐答案

No operator ">>" matches these operands operand types are: std::istream >> double

这似乎是一条奇怪的错误消息.毕竟,可以很快想到一个示例程序,该程序从 std :: cin 流化一个 double ,这是一个 std :: istream .那么这是怎么了?

This might seem like a strange error message. After all, one could fairly quickly come up with an example program that streams a double from std::cin, which is a std::istream. So what is wrong here?

答案来自此错误消息后面的一堆笔记.(是的,这可能是一个令人生畏的混乱,但是这里有注释可以帮助您诊断问题.不,我不希望整个混乱都被复制到问题中,因为它很大而且大部分都不相关.)候选运算符列表中的某个位置是

The answer comes in that mess of notes that follows this error message. (Yes, it can be an intimidating mess, but the notes are there to help diagnosing the problem. No, I do not expect the entire mess to be copied into the question, since it is large and most of it is not relevant.) Somewhere in the list of candidate operators is

operator>>(double& __f)

这是允许流传输 double 的运算符.但是,请注意参数的类型-不是 double ,而是 double& .流的目标必须命名一个变量,而不仅仅是提供一个值.您的情况下,尝试在>>中使用z.real()类似于在>>中尝试3.1 . z.real() 3.1 的类型均为 double ,因此您可以对一个执行的操作可以对另一个执行的操作.希望您不相信可以通过将新值流式传输到 3.1 中来更改数学.同样,您不能将值流式传输到返回 double 的函数中.

This is the operator that allows streaming a double. However, note the type of the parameter – it is not double, but double&. The target of the stream must name a variable, not merely provide a value. In your case, attempting in >> z.real() is similar to attempting in >> 3.1. The types of z.real() and 3.1 are both double, so what you can do to one you can do to the other. Hopefully you do not believe you can change mathematics by streaming a new value into 3.1. Similarly, you cannot stream a value into a function that returns a double.

一种解决方案是使函数返回流运算符期望的结果,如 double&real()(添加与号并删除 const ).但是,提供对私有成员的公共非常量引用会破坏封装.该成员在那时也可能是公开的.另外,您的项目不允许这样做.让我们寻找一种更好的方法.

One solution is to make your function return what the stream operator expects, as in double& real() (add an ampersand and remove const). However, providing a public non-const reference to a private member destroys encapsulation; the member might as well be public at that point. Plus, your project does not allow it. Let's look for a better approach.

更常见的解决方案是使 operator>>> 成为您班上的 friend 的朋友,以便可以设置私有成员.这需要添加行

A more common solution is to make operator>> a friend of your class so that it can set the private members. This requires adding the line

friend std::istream& operator>>(std::istream& in, complex& z);

您的班级定义.完成之后,您的 operator>> 的实现可以绕过访问器函数来访问私有数据成员.注意:如果需要的话, operator>> 的定义可以保留在类定义之外的正确位置.

to your class definition. After that is done, your implementation of operator>> can access the private data members, bypassing the accessor functions. Note: the definition of operator>> can stay right where it is, outside the class definition, if that is desirable.

std::istream& operator>>(std::istream& in, complex& z) {
    in >> z.realX;
    in >> z.imaginaryY;
    return in;
}

更round回的方法是使用建筑和分配而不是友谊.在更复杂的情况下,这可以减少代码重复.但是,在您的情况下,它会触发警告,因为您的课程违反了三人制规则具有复制构造函数,但没有赋值运算符.尽管如此,编译器会自动为您生成显式副本构造函数.您可以通过注释掉副本构造函数来解决警告.

A more roundabout approach uses construction and assignment instead of friendship. This might reduce code duplication in more complex cases. However, in your case it triggers a warning because your class violates the Rule of Three by having a copy constructor but no assignment operator. Still, your explicit copy constructor is what the compiler would automatically generate for you. You could address the warning by commenting out your copy constructor.

std::istream& operator>>(std::istream& in, complex& z) {
    double real;
    double imaginary;
    
    in >> real;
    in >> imaginary;
    z = complex{real, imaginary};
    
    return in;
}

对于像您的 complex 类这样简单的事情,我会很友善.

For something as simple as your complex class, I would go with friendship.

这篇关于没有运算符“&gt;".与这些操作数匹配的操作数类型为:std :: istream&gt;&gt;双倍的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆