3

例如,如果我想通过

ostream& std::ostream::operator << (int i);  

进入一个函数,例如

void func(ostream& (*out)(int), ...);

那我该怎么做呢?

正在做

func(std::ostream::operator << (int))

肯定行不通

typedef ostream& (*out)(int);
out o = std::ostream::operator << (int);
func(o);

尝试分配 o 时引发编译时错误。那么如何指向重载运算符呢?(在这种情况下,强制类型输出也不起作用)


在玩弄了代码之后,我现在的问题是:为什么它是非成员、重载的运算符,即

ostream& operator << (ostream&, classX) 

返回 void* 而不是指向函数的指针?

如果我做

typedef ostream& (*out)(ostream&,classX);

我只能做到

void* v = ostream& operator << (ostream&,classX);

并不是

out o = ostream& operator << (ostream&,classX);

打印错误消息

190: error: invalid conversion from 'void*' to 'std::ostream& (*)(std::ostream&, classX)'
4

2 回答 2

3

取决于您如何重载运算符。

函数的签名(指向的指针的类型)是:

  • RETURN_TYPE(*)(PARAMETERS_TYPES)如果它是一个全局函数。
  • RETURN_TYPE (CLASS_NAME::*)(PARAMETERS_TYPES)如果它是一个成员函数。

如果你有一个被调用的函数f和一个获取指向函数的指针作为参数的函数,f 的传递方式如下:

  • g(f)如果 f 是一个全局函数。
  • g(&CLASS_NAME::f)如果 f 是 CLASS_NAME 类的成员函数。

请注意,函数指针和成员函数指针不兼容。

因此,如果您的运算符作为成员函数重载,则operator+=应该使用第二个版本。如果没有,你应该使用第一个。

于 2013-08-02T09:21:09.623 回答
1

我会在这里简化分配。无需指定整个签名,因为可以从左侧的类型推断出正确的重载。

#include <iostream>
using namespace std;

struct Foo
{
    int x;
};

ostream& operator<< (ostream &a, const Foo& b)
{
    return a << b.x;
}

typedef ostream& (*Func) (ostream &, const Foo&);

int main() {
    Func func = &operator<<;
    (*func)(cout, Foo{42});
}
于 2016-03-14T22:59:12.567 回答