Function-To-Function-Pointer "Decay"

Why don't these functions decay to a function pointer?

You could make your class store a function pointer instead, like this:

template <typename Ret, typename ...Args>
class MyClass
{
public:
MyClass(Ret (*function)(Args...)) : function(function) {}
Ret (*function)(Args...);
};

Then you can store the lambda, by explicitly decaying it to a function pointer:

MyClass foo( + []() {return 5; });

and then only one class will be instantiated per function signature (whether it's a lambda or a function).

Here's a demo.

No Function to Pointer Decay during Assignment

why doesn't A decay to a pointer to a function?

The error message says that a function (int()) cannot be implicitly converted to a pointer to a pointer to a function (int (**)()), because the type of the expression (A) is a function.

The function would decay if there was a valid conversion sequence to the target type through the decayed type. But there isn't such conversion sequence, and so the program is ill-formed.

What is array to pointer decay?

It's said that arrays "decay" into pointers. A C++ array declared as int numbers [5] cannot be re-pointed, i.e. you can't say numbers = 0x5a5aff23. More importantly the term decay signifies loss of type and dimension; numbers decay into int* by losing the dimension information (count 5) and the type is not int [5] any more. Look here for cases where the decay doesn't happen.

If you're passing an array by value, what you're really doing is copying a pointer - a pointer to the array's first element is copied to the parameter (whose type should also be a pointer the array element's type). This works due to array's decaying nature; once decayed, sizeof no longer gives the complete array's size, because it essentially becomes a pointer. This is why it's preferred (among other reasons) to pass by reference or pointer.

Three ways to pass in an array1:

void by_value(const T* array)   // const T array[] means the same
void by_pointer(const T (*array)[U])
void by_reference(const T (&array)[U])

The last two will give proper sizeof info, while the first one won't since the array argument has decayed to be assigned to the parameter.

1 The constant U should be known at compile-time.

Why can I assign to a function pointer both a reference to a function a the function itself?

This is pretty much an exact duplicate of this question

The answer is that functions can be implicitly converted to function pointers (similar to array to pointer decay) per the spec.

automatic decay of lambda to function pointer when passing to template function

You can change your lambda to use the unary + operator: +[]{ return 0; }

This works because unary plus can be applied to pointers, and will trigger the implicit conversion to function pointer.



Related Topics



Leave a reply



Submit