What really happens when using templates?

I am a bit confused about concepts with templates. Namely, if you have a function like this:

template<typename T>
void DoubleValue(T &param)
{
    param *= 2;
}

      

How does the compiler know what types I can pass to this function? Does it check all known types if the code works with that type? Are there performance issues?

+3


source to share


3 answers


Unlike generics in Java or C # (where the type parameter acts like boost::any

, that is, compiler-protected, time-tested void*

), the [class / function] template is not [class / function]. It is used to create ad-hoc [class / function] at the time of instantiation (not to be confused with an object instance).

Instance creation can be explicit:

// Hey compiler, please generate code for DoubleValue<int>.
template void DoubleValue<int>(int &param);

      



... or implicit:

int main() {
    // Hey compiler, I want to call DoubleValue<float>.
    // Please generate the code if it not done already.
    return DoubleValue(1.5f);
}

      

All of this is done at compile time.

+9


source


The compiler doesn't do anything until you actually use (read: instantiate) your template, for example:

SomeType x;
DoubleValue(x);

      

At this point, the compiler tries to generate code for the function DoubleValue(SomeType&)

. Compilation is done if the code can be generated (in your example, if the type SomeType

has an operator *=

).

Another example:



template<typename T>
void SomeFunc(T param)
{
    param.foo();
}

SomeType x;
SomeFunc(x);

      

The activation SomeFunc

will succeed if it SomeType

has a method foo

- if it doesn't, the compiler will fail. This is sometimes called compile-time polymorphism.

I'm short: Templates are a convenient way to generate code on demand (nothing happens while you actually use

(read: instantiate)).

I hope this helps.

+2


source


No, he doesn't test it with all types. the compiler only generates code with the type you intend to use for treatment, and if that is not possible, you will get a compilation error. Pattern is static polymorphism to avoid rewriting the same code for multiple types So for example:

  int x=5;
  DoubleValue(x);

      

the compiler will only generate a function with int and as a signature

void DoubleValue(int &param)
{
    param *= 2;
}

      

+1


source







All Articles