Home > Enterprise >  Template parameter vs function argument
Template parameter vs function argument

Time:11-12

I am writing some code and realized I don't know which would be better to use. What would the benefits/drawbacks of each? I am currently using the one with the const uint16_t, because I thought templating it would expand the binary by creating unique function signatures. Thanks in advance for anyone who wants to help explain this!

template<typename T, uint16_t response_size>
T get_endpoint_value(const uint16_t endpoint_id)

vs

template<typename T, uint16_t response_size, uint16_t endpoint_id>
T get_endpoint_value()

vs

template<typename T>
T get_endpoint_value(serial::Serial* serial, 
const uint16_t endpoint_id, const uint16_t response_size)

Where endpoint_id is just a value that gets copied into a buffer. response_size is used to size a uint_t buffer[response_size] during a data transfer over serial.

CodePudding user response:

The template-based version allows the compiler to inline the call, because the address of the function is known at compile-time. The disadvantage you cannot change the value of the template parameters at runtime.

So if you want to change the parameters in runtime, you have to use parameters and not template arguments. Note that, by runtime, I mean when your application is running and by compile time I mean when your application is compiling. I would go with templates if that is not needed in runtime and the value of response_size/endpoint_id is fixed/known at compile time

CodePudding user response:

Summary: Use function arguments unless you have a special reason not to.

If you don't know your arguments at compile time, you don't have a choice - you cannot use it at a template parameter. Let's assume you know it at compile time.

If the function is so small that the compiler inlines it, then the result is the same for both function arguments and template parameters. If not, then most likely the time spent on passing function arguments is negligible, but the effect of the code bloat caused by additional template instantiation may be important.

Now, the special reasons to prefer template parameters:

  1. This may allow you to avoid dynamic memory allocation inside the function. For example, if you need a buffer with a size response_size which you can declare as std::vector<char> buf(response_size);. But, if response_size is a template parameter, you can declare it as std::array<char, response_size> buf;, avoiding dynamic memory.
  2. You know about an important compile-time optimization available for compile-time constants only. For example, integer division is slow, but if the divisor is a compile-time constant, it may be replaced with a sequence of faster operations.
  • Related