I know of one way to call a function :
func(x, y);
Are there more ways to call a function?
Functions can be invoked
explicitly, by providing an argument parenthesis after a designation of the function (in the case of constructors this is decidedly not formally correct wording, since they don't have names, but anyway),
implicitly, in particular destructors and default constructors, but also implicit type conversion,
via operators other than the function call operator ()
, in particular the copy assignment operator =
and the dereferencing operator ->
,
in a placement new
expression, invocation of a specified allocation function by placing an argument parenthesis right after new
(not sure if this counts as a separate way).
In addition library facilities can of course invoke functions for you.
I think the above list is exhaustive, but I'm not sure. I remember Andrei Alexandrescu enumerated the constructs that yielded callable thingies, in his Modern C++ Design book, and there was a surprise for me. So there is a possibility that the above is not exhaustive.
Arbitrary functions can be invoked:
using f(arguments...)
notation
via a pointer to the function (whether member or non-)
via a std::function
- (will check the implementation's left unspecified, though I'd expect it to use a pointer to function or pointer to member function under the covers so no new language features)
Class-specific functions are also invoked in certain situations:
constructors are invoked when objects are created on the stack, and when static/global or thread-specific objects or dynamically-allocated objects are dynamically initialised, or with placement new
, and as expressions are evaluated
destructors are invoked when objects leave scope, are delete
d, threads exit, temporaries are destroyed, and when the destructor is explicitly called ala x.~X()
all manner of operators ([]
, +=
, ==
, <
etc.) may be invoked during expression evaluation
Arbitrary non-member functions may be run by:
functions may be run due to earlier std::atexit()
or std::at_quick_exit()
calls, and if they throw std::terminate
may run
thread creation and asynchronous signals (again the interfaces accept pointer to functions, and there's no reason to think any implementation has or would use any other technique to achieve dispatch)
Specific functions are triggered in very specific situations:
main()
is executed by the runtime
std::unexpected
, std::unexpected_handler
, std::terminate
are invoked when dynamic exception specifications are violated
It's also possible to use setjmp
and longjmp
to "jump" back into a function... not quite the same thing as calling it though.
Though not truly "C++", it's also possible to arrange function execution using inline assembly language / linked assembler, writing to executable memory.
C++ is a fairly flexible language and therefore this is a very vague question as there can be a 100 different ways of "calling a function" given not limitations of what is allowed.
Remember a function is only really a block of code sitting somewhere in memory. The act of "calling" a function is to some extent the following:
In the end all methods come down to this happening in some way or another.
Perhaps not 100% relevant here but remember that in C++ functions can be members of a class.
class MyClass{
public:
void myFunction(int A);
}
Usually what happens in this case is that the class object is passed as a first parameters.
So the function call:
myObject.myFunction(A)
is in a way equivalent to calling:
myFunction(myObject,A)
if you look at function object you will see this kind of behavior. Function objects reference
Ok so here is a short list:
In a threaded environment things might also get more interesting as you might want to call functions in a different thread.
Lastly I suppose it's a good idea to mention meta-programming and the idea of RTTI. This is not as strongly supported as say in languages like c#. If this is to be manually implemented one would be able to at run-time search the list of available functions and call one. By this method it would be possible to match a function at run-time vs a string name. This is to some extent impemented by Qt's MOC system.
What are we counting as a different way? If I have a function that is a member of a class foo, then I might call it like this:
foo.func(x, y);
If I have a pointer to foo, I would do this
foo->func(x, y);
If I had a class bar that was derived from foo, I might call foo's constructor with an initialization list
bar::bar(const int x, const int y) : foo(x, y) {}
A constructor is just a function, after all.