Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which approach is better for supplying compile time constants to a function ? Function argument vs. Template parameter

I have logging function being called at several places throughout the code. To every log, I have to supply 2 compile time constants. There are 2 approaches to accomplish:

(1) Function argument:

template<typename T>
void log (const T &obj, const int LINE, const int COUNT)
{
  // T is used for some purpose
  if(debug)
    logging(obj.out(), LINE, COUNT);
}

call it as,

log(str, __LINE__, __COUNTER__);

(2) Template parameter:

template<typename T, int LINE, int COUNT>
void log (T &obj)
{
  // T is used for some purpose
  if(debug)
    logging(obj.out(), LINE, COUNT);
}

call it as,

log<__LINE__, __COUNTER__>(str);

I am not able to decide, because 1st approach offers simplicity, but we are passing constant at compile time. 2nd approach is perfect, but compilation time would probably increase. This task is tedious, and I haven't implemented any of them yet, so I don't have any bench mark.

It will be a great help if someone can answer this from their experience/knowledge.

like image 699
iammilind Avatar asked Dec 19 '11 06:12

iammilind


People also ask

What is the difference between the function template and template function?

"A function template is a template that is used to generate functions. A template function is a function that is produced by a template. For example, swap(T&, T&) is a function tem-plate, but the call swap(m, n) generates the actual template function that is invoked by the call."

What is used for a function to execute at compile time?

In computing, compile-time function execution (or compile time function evaluation, or general constant expressions) is the ability of a compiler, that would normally compile a function to machine code and execute it at run time, to execute the function at compile time.

What is a template argument?

A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

Which one is suitable syntax for function template?

Which one is suitable syntax for function template? Explanation: Both class and typename keywords can be used alternatively for specifying a generic type in a template.


2 Answers

Since the choice between these two makes a difference to the calling code, I would recommend logging via a macro. Then you don't have to worry now about which of these is better, because it's easy to switch between them.

Once you have your real application written, you can mess with the macro definition to compare the two. Or not, if there are more productive areas to optimize. If it turns out to make a big difference, you can even leave it open to the build config to decide whether to use -DLOGGING_COMPILES_QUICKLY or -DLOGGING_RUNS_QUICKLY.

Another potential benefit of a macro: you could arrange that the first argument is evaluated if and only if debug is true. I don't know what the interface of str is, or where those objects come from, but if it costs anything to produce the right value to pass to log, and then log doesn't use it in the non-debug case, then that's a potential waste of runtime.

like image 197
Steve Jessop Avatar answered Nov 17 '22 21:11

Steve Jessop


I would go with the first option. The performance impact of passing two integers is negligible. The optimizer will also probably inline the function call in which case there would be no difference between the two. The second option I think is a bad idea, since you will be creating a lot of versions of the same function, for no reason.

like image 3
ronag Avatar answered Nov 17 '22 21:11

ronag