English 中文(简体)
运算符 {{% 必须完全采纳一个参数 [重复]
原标题:operator << must take exactly one argument [duplicate]

a.h (小时)

#include "logic.h"
...

class A
{
friend ostream& operator<<(ostream&, A&);
...
};

逻辑学.cpp

#include "a.h (小时)"
...
ostream& logic::operator<<(ostream& os, A& a)
{
...
}
...

当我编集时,它写道:

std: ostream& 逻辑 :: operator< & lt; (std:: ostream&, A&) 必须精确使用一个参数 。

有什么问题?

最佳回答

问题是,你把它定义在类内,

a) 意指隐含的第二个参数( < code> this )和

(b) 它不会做你想做的事,即扩展 std::os流

您必须定义它为自由函数 :

class A { /* ... */ };
std::ostream& operator<<(std::ostream&, const A& a);
问题回答

朋友函数不是成员函数, 问题在于您是否声明 operator<< A 的朋友 :

 friend ostream& operator<<(ostream&, A&);

然后尝试将其定义为类中 logic 的成员函数

 ostream& logic::operator<<(ostream& os, A& a)
          ^^^^^^^

您是否不清楚 logic 是类还是命名空间?

错误是因为您曾经试图定义一个成员 operator<< , 需要两个参数, 这意味着它需要三个参数, 包括隐含的 this 参数。 操作员只能使用两个参数, 所以当您写入 a < b b < /code> 时, 两个参数是 b

您想要将 ostream& 运算符 & lt; (ostream & amp;, const A&) 定义为 < strong > non 成员函数, 绝对不是 < code> logic 的成员, 因为它与该类别无关!

std::ostream& operator<<(std::ostream& os, const A& a)
{
  return os << a.number;
}

I ran into this problem with templated classes. Here s a more general solution I had to use:

template class <T>
class myClass
{
    int myField;

    // Helper function accessing my fields
    void toString(std::ostream&) const;

    // Friend means operator<< can use private variables
    // It needs to be declared as a template, but T is taken
    template <class U>
    friend std::ostream& operator<<(std::ostream&, const myClass<U> &);
}

// Operator is a non-member and global, so it s not myClass<U>::operator<<()
// Because of how C++ implements templates the function must be
// fully declared in the header for the linker to resolve it :(
template <class U>
std::ostream& operator<<(std::ostream& os, const myClass<U> & obj)
{
  obj.toString(os);
  return os;
}

Now: * My toString() function can t be inline if it is going to be tucked away in cpp. * You re stuck with some code in the header, I couldn t get rid of it. * The operator will call the toString() method, it s not inlined.

运算符 & lt; & lt; 的正文可以在朋友条款中或类外声明。 两种选项都是丑陋的 。 () : ()

或许我误会了 或者漏掉了什么 但只是前方声明操作员的模板 并没有连接到Gcc

这个也有效:

template class <T>
class myClass
{
    int myField;

    // Helper function accessing my fields
    void toString(std::ostream&) const;

    // For some reason this requires using T, and not U as above
    friend std::ostream& operator<<(std::ostream&, const myClass<T> &)
    {
        obj.toString(os);
        return os;
    }
}

我认为,如果您使用一个没有模板的母类来执行操作员 & lt; & lt;, 并使用虚拟 String () 方法, 您也可以避免在信头中强制声明的诱惑问题 。

操作员超载包括成员超载和非成员超载功能,不能混合。 https://condor.depaul.edu/entomuro/courses/262/notets/ ecture3.html

如果您将 operator<< 定义为成员函数, 它将会有与使用非成员 operator < 不同的解构语法。 一个非成员 operator<< 是一个二进制运算符, 其中成员 operator < 是一个非成员运算符 。

// Declarations
struct MyObj;
std::ostream& operator<<(std::ostream& os, const MyObj& myObj);

struct MyObj
{
    // This is a member unary-operator, hence one argument
    MyObj& operator<<(std::ostream& os) { os << *this; return *this; }

    int value = 8;
};

// This is a non-member binary-operator, 2 arguments
std::ostream& operator<<(std::ostream& os, const MyObj& myObj)
{
    return os << myObj.value;
}

那么... 您如何真正称呼它们? 运算符在某些方面是奇特的, 我将挑战您在您头上写下 < code> operator<< > (...) 语法, 以便让事情有意义 。

MyObj mo;

// Calling the unary operator
mo << std::cout;

// which decomposes to...
mo.operator<<(std::cout);

或者你可以试图调用非会员二进制操作员:

MyObj mo;

// Calling the binary operator
std::cout << mo;

// which decomposes to...
operator<<(std::cout, mo);

您没有义务让这些操作员在将其变成成员函数时直觉地行为, 您可以定义 < code> operator< & lt; (int) 以左移某个成员变量, 如果您想要的话, 理解人们可能有点被疏远, 无论您写多少评论 。

几乎最后,也许有两种情况下 操作员电话的分解都是有效的, 你可能会陷入麻烦 在这里,我们将推迟 对话。

最后,请注意写出一个像二进制运算符的无名成员运算符(因为您可以将成员运算符变成虚拟...................................

struct MyObj
{
    // Note that we now return the ostream
    std::ostream& operator<<(std::ostream& os) { os << *this; return os; }

    int value = 8;
};

这个语法现在会刺激很多编码员...

MyObj mo;

mo << std::cout << "Words words words";

// this decomposes to...
mo.operator<<(std::cout) << "Words words words";

// ... or even further ...
operator<<(mo.operator<<(std::cout), "Words words words");

请注意 < code> cout 是如何在此链条中的第二个参数... 。 奇数?

关键点是 logic:: before operator<< , 被定义为朋友函数。

logic:: 仅在成员函数之前添加。 我知道这类似于告诉汇编者此函数是成员函数并给予相应权限(例如访问私人功能) 。

换句话说,正如@asaelr 和 @Morteza 所提到的,“当定义一个朋友函数时,您不使用该类的名称来限制朋友函数的名称”。

因此,我们应该删除 logic: before operator<<





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签