Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing functions in C++

Tags:

c++

c++17

Suppose I want to write a function that calls a nullary function 100 times. Which of these implementations is best and why?

template<typename F> void call100(F f) {     for (int i = 0; i < 100; i++)         f(); }  template<typename F> void call100(F& f) {     for (int i = 0; i < 100; i++)         f(); }  template<typename F> void call100(const F& f) {     for (int i = 0; i < 100; i++)         f(); }   template<typename F> void call100(F&& f) {     for (int i = 0; i < 100; i++)         f(); } 

Or is there a better implementation?

Update regarding 4

struct S {     S() {}     S(const S&) = delete;     void operator()() const {} };  template<typename F> void call100(F&& f) {     for (int i = 0; i < 100; i++)         f(); }  int main() {     const S s;     call100(s); } 
like image 737
Andrew Tomazos Avatar asked Apr 14 '19 11:04

Andrew Tomazos


People also ask

How do you pass a function in C?

Function Call When calling a function with a function parameter, the value passed must be a pointer to a function. Use the function's name (without parentheses) for this: func(print); would call func , passing the print function to it.

Can we pass of function in C?

We cannot pass the function as an argument to another function. But we can pass the reference of a function as a parameter by using a function pointer. This process is known as call by reference as the function parameter is passed as a pointer that holds the address of arguments.

What is passing a function?

Passing Functions as Arguments. Functions are data, and therefore can be passed around just like other values. This means a function can be passed to another function as an argument. This allows the function being called to use the function argument to carry out its action.

What is passing argument in C?

Arguments in C and C++ language are copied to the program stack at run time, where they are read by the function. These arguments can either be values in their own right, or they can be pointers to areas of memory that contain the data being passed. Passing a pointer is also known as passing a value by reference.

How to pass a pointer to a function in C?

Passing pointers to functions in C. C programming allows passing a pointer to a function. To do so, simply declare the function parameter as a pointer type.

What are the parameter passing techniques in C++?

Parameter Passing Techniques in C/C++. There are different ways in which parameter data can be passed into and out of methods and functions. Let us assume that a function B() is called from another function A(). In this case A is called the “caller function” and B is called the “called function or callee function”.

How to pass a function as an argument in C/C++?

Passing a function as an argument is a useful concept in C/C++. This concept has already been used while passing a custom comparator function as an argument in std::sort() to sort a sequence of objects as per the need. In this article, we will discuss different ways to design functions that accept another function as an argument.

Can a function be passed as a parameter to a function?

The following function ( print) is an example of a function which could be passed to func as a parameter because it is the proper type: When calling a function with a function parameter, the value passed must be a pointer to a function. Use the function's name (without parentheses) for this: would call func, passing the print function to it.


2 Answers

I would use the first one (pass the callable by value).

If a caller is concerned about the cost of copying the callable, then they can use std::ref(f) or std::cref(f) to pass it using reference_wrapper.

By doing this, you provide the most flexibility to the caller.

like image 188
Marshall Clow Avatar answered Sep 23 '22 23:09

Marshall Clow


The only runtime cost of

template<typename F> void call100(F&& f) {   for (int i = 0; i < 100; ++i)     f(); } 

is that it can have more versions (copies of code) if you pass f in multiple ways. With MSVC or the gold linker with ICF, those copies only cost compile time unless they differ, and if they differ you probably want to keep them.

template<typename F> void call100(F f) {   for (int i = 0; i < 100; ++i)     f(); } 

this one has the advantage of being value semantics; and following the rule of taking values unless you have good reason not to is reasonable. std::ref/std::cref let you call it with a persistant reference, and for prvalues c++17 guaranteed elision will prevent a spurious copy.

As a joke you could do:

template<typename F> void call100(F&& f) {   for (int i = 0; i < 99; ++i)     f();   std::forward<F>(f)(); } 

but that relies on people having && overloads on their operator(), which nobody does.

like image 35
Yakk - Adam Nevraumont Avatar answered Sep 25 '22 23:09

Yakk - Adam Nevraumont