我正在玩std::function<>
和operator
,以使C ++语句看起来像功能语言(F#
),并发现operator()
之间存在差异和operator<<
。我的代码:
功能1(操作员过载):
function<int(int)> operator>>(function<int(int)> f1, function<int(int)> f2)
{
function<int(int)> f3 = [=](int x){return f1(f2(x));};
return f3;
}
功能2(操作员过载):
function<int(int, int)> operator>>(function<int(int, int)> f1, function<int(int)> f2)
{
function<int(int, int)> f3 = [=](int x,int y){return f2(f1(x, y));};
return f3;
}
功能3(操作员过载):
function<int(int)> operator()(function<int(int, int)> f1, int x)
{
function<int(int)> f2 = [=](int y){return f1(x, y);};
return f2;
}
当功能1和功能2(或操作员过载)时,功能3发出错误:
error: ‘std::function<int(int)> operator()(std::function<int(int, int)>, int)’ must be a nonstatic member function
function<int(int)> operator()(function<int(int, int)> f1, int x)
^
为什么operator()
需要是非静态成员?
我认为它与What is the difference between the dot (.) operator and -> in C++?不同在这个问题中,答案是用指针来解释的。但在这里我使用的是简单的operator()
和operator>>
,它与指针无关。
答案 0 :(得分:4)
这些是语言设计者决定的规则。 std::function
允许语法看起来像是类本身的一部分(在你的情况下是operator()
),该类的接口应该由类本身控制。
标准在
中定义了这个13.5.4函数调用[over.call]
1
=
应为具有任意数量参数的非静态成员函数。 [...]
强调我的
其他运营商也做出了类似的决定,例如分配[]
,下标->
和类成员访问>>
,而对于像{{1}}这样的运营商,他们认为这是有意义的允许在两个(几乎)任意类之间添加运算符,而与类的接口本身无关。
答案 1 :(得分:2)
operator>>()
可以作为非静态成员或独立函数调用,具体取决于它是如何为左侧数据类型定义的。声明:
lhs >> rhs
可以解析为:
lhs.operator>>(rhs) // non-static member
或者:
operator>>(lhs, rhs) // standalone function
另一方面, operator()
不能作为独立函数调用。它必须在左侧有一些东西来调用它。声明:
lhs(arguments)
只能解析为:
lhs(arguments) // only if lhs is an actual function
或者:
lhs.operator()(arguments) // must be a non-static member
没有允许语句的C ++语言语法:
lhs(arguments)
解析为:
operator()(lhs, arguments)
答案 2 :(得分:1)
operator>>()
可以作为非成员函数重载,但不能operator()
重载。 operator()
只能是class
或struct
的非静态成员函数。
来自标准:
13.5.4函数调用 [over.call]
1
operator()
应为具有任意数量参数的非静态成员函数。它可以有默认参数。它实现了函数调用语法postfix-expression(expression-list opt)
其中 postfix-expression 评估为一个类对象,并且可能为空的表达式列表匹配该类的
operator()
成员函数的参数列表。因此,如果x(arg1,...)
存在且操作符被选为最佳匹配,则x.operator()(arg1, ...)
类型对象x
的{{1}}被解释为T
通过重载解析机制(13.3.3)起作用。