Why is operator ()
of stateless functor not allowed to be static
? Stateless lambda objects are convertible to pointers to free functions having the same signature as their operator ()
.
Stephan T. Lavavej on p. 6 points out that conversion to a function pointer is just an operator FunctionPointer()
(cite). But I can't obtain a corresponding pointer to operator ()
as to non-member function. For functor struct F { void operator () () {} }
it seems to be impossible to convert &F::operator ()
to instance of type using P = void (*)();
.
Code:
struct L
{
static
void operator () () const {}
operator auto () const
{
return &L::operator ();
}
};
The error is
overloaded 'operator()' cannot be a static member function
but operator ()
is not overloaded.
Per standard 13.5/6,
An operator function shall either be a non-static member function or be a non-member function and have
at least one parameter whose type is a class, a reference to a class, an enumeration, or a reference to an
enumeration.
Additionally, in 13.5.4 it is stated that
operator()
shall be a non-static member function with an arbitrary number of parameters. It can have
default arguments. It implements the function call syntax
postfix-expression
(
expression-list
opt
)
where the
postfix-expression
evaluates to a class object and the possibly empty
expression-list
matches
the parameter list of an
operator()
member function of the class. Thus, a call
x(arg1,...)
is interpreted
as
x.operator()(arg1, ...)
for a class object
x
of type
T
I would think that there's no technical reason to forbid this (but not being familiar with the de-facto cross-vendor C++ ABI (Itanium ABI), I can't promise anything).
There's however an evolutional issue about this at https://cplusplus.github.io/EWG/ewg-active.html#88 . It even has the [tiny] mark on it, making it a somewhat "trivial" feature under consideration.
I can't see any technical reason to forbid a static auto operator()( ... )
. But it's a special case, so it would complicate the standard to add support for it. And such complication is not necessary, because it's very easy to emulate:
struct L
{
static void func() {}
void operator()() const { func(); }
operator auto () const
{
return &L::func;
}
};
See Johannes' answer for some possibly useful extra info.
A simple, a little bit dirty workaround until the relevant committee considers this trivial feature:
Glob operators are syntactically similar to the constructors.
Thus, you can't write a
static MyClass::operator()(...);
It was made simply impossible, because a committee decided so on unclear reasons. I would be so happy if I could talk with one of their members, to ask, what was in their mind as they decided so. Unfortunately, he probably wouldn't understand my question, because he never programmed c++. He only worked on its docs.
Now they need some decades of
- debates
- consultations
- meetings
- and considerations
to implement a trivial feature. I suspect the feature may be made available around in c++3x, and on emulated machines it may be even tried out.
Until then, you can try to write:
MyClass::MyClass(...);
In both cases you can call MyClass(...);
.
Of course it is useful mainly if MyClass
is a singleton. And, I would say it is a hack. Furthermore, it allocates a sizeof(MyClass)
on the stack which may be bad in the performance / efficiency side.
Furthermore, this will be in essence a constructor, and constructors can't return anything. But you can avoid this by storing the result in the instance, and then casting it by a cast operator to anything you wish to.