Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why did the C++ designers choose not to allow non-member operator()()?

I am just playing with std::function<> and operators, to make C++ statements look like Functional Languages(F#) and found out that there is a difference between operator() and operator<<. My code :

Function 1 (Operator Overload):

function<int(int)> operator>>(function<int(int)> f1, function<int(int)> f2)
{
  function<int(int)> f3 = [=](int x){return f1(f2(x));};
  return f3;
}

Function 2 (Operator Overload):

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;
}

Function 3 (Operator Overload):

function<int(int)> operator()(function<int(int, int)> f1, int x)
{
  function<int(int)> f2 = [=](int y){return f1(x, y);};
  return f2;
}

while the Function 1 and Function 2 ( or Operator Overload ), Function 3 gives out error that :

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)
                                                                    ^

Why do operator() needs to be non-static member? I think its different than What is the difference between the dot (.) operator and -> in C++? In that question the answer is explained in terms of pointers. But here I am using simple operator() and operator>>, which has nothing to do with pointers.

like image 757
0x6773 Avatar asked Mar 16 '23 23:03

0x6773


2 Answers

Those are the rules that the language designers decided on. operator() allows for a syntax which looks like it is part of the class itself (std::function in your case) and the interface of that class should be controlled by the class itself.

The standard defines this in

13.5.4 Function call [over.call]

1operator() shall be a non-static member function with an arbitrary number of parameters. [...]

emphasis mine

Similar decisions were made for other operators like assignment =, subscripting [] and class member access ->, while for operators like >>, they decided that it makes sense to allow adding operators between two (almost) arbitrary classes independently of the class' interface itself.

like image 96
Daniel Frey Avatar answered Mar 18 '23 11:03

Daniel Frey


operator>>() can be called as a non-static member or as a standalone function, depending on how it is defined for the left-hand data type. The statement:

lhs >> rhs

Can resolve as either:

lhs.operator>>(rhs) // non-static member

Or:

operator>>(lhs, rhs) // standalone function

operator(), on the other hand, cannot be called as a standalone function. It must have something on the left-hand side to invoke it. The statement:

lhs(arguments)

Can only resolve as:

lhs(arguments) // only if lhs is an actual function

Or:

lhs.operator()(arguments) // must be a non-static member

There is no C++ language syntax that would allow the statement:

lhs(arguments)

to resolve as:

operator()(lhs, arguments)
like image 33
Remy Lebeau Avatar answered Mar 18 '23 11:03

Remy Lebeau