Difference between passing pointers as function argument vs non type template parameters

129 Views Asked by At

I am unable to understand the difference between

  1. Passing pointers as function arguments
  2. Passing pointers as non type template parameter

Can you please help understand what optimization is achieved by choosing 2 (Particularly from the context of fast delegates as explained here and as used here)?

Some of my confusions surrounding the use of pointers as non type parameters are

  1. When pointers are resolved at compile time how does the compiler know what the pointer is pointing to?
  2. How is a member function pointer resolved at compile time when member functions can be virtual?
1

There are 1 best solutions below

6
On

When pointers are resolved at compile time how does the compiler know what the pointer is pointing to?

Because that's how templates work. For all of their complexity, the basic idea of a template is very simple.

A template is a (smart) macro. When you instantiate a template, you are basically creating a copy of the template, where every use of the template parameters is replaced by the corresponding arguments passed at instantiation-time.

So this:

template<func_ptr ptr>
void func1();
{
  ptr();
}

func1<some_func>();

Is functionally equivalent to this:

void func2()
{
  some_func();
}

func2();

How does the compiler know that func2 will call some_func? Because that's literally what you wrote in the code. How does the compiler know that func1<some_func> will call some_func? Because that's literally what you wrote in the code when you named it func1<some_func>.

How is a member function pointer resolved at compile time when member functions can be virtual?

That all depends on what you mean by "resolved".

Assuming that the class the function is invoking the member pointer on is not final (you can't inherit from a final class, so the compiler knows exactly which function to call), the compiler cannot determine exactly which override will be called.

However, the compiler does know where that override is. Assuming we're talking about a vtable-based implementation of virtual functions, a member pointer contain an index into the vtable that the compiler would use to find the actual override function. But if the member pointer is known at compile time, that means the index is also known at compile-time. So the compiler need not dynamically index into the table; it can statically index it.

So in a way, it can be considered to have "resolved" the override at compile time. At least, to the extent possible.