tags:

views:

91

answers:

3

I have a got a question. Which is the better of doing it.

typedef enum{
  One = 1,
  Two = 2
} Number;

template< typename T, Number num >
void foo( const T& param )
{
}

or 

template< typename T >
void foo( const T& param, Number num )
{
}

What basically I am looking for is, how are these two methods different? If I have to use any of these which one should I choose and why?

+2  A: 

I'd go for the second unless foo() is extremely performance critical, since I think it's clearer.

As for the differences:

The first one will be compiled into different versions for different Number values. This may allow the compiler to make more optimisations depending how num is used.

The second will only have different versions for different T, and will select for different num at run-time.

The first might be marginally faster, but the second will generate less code (which might be faster depending on memory pressure).

Douglas Leeder
+10  A: 

It really depends on what you want to do. If the num value is a template parameter then it must be specified at compile time. If it is a function parameter then it can be specified at runtime.

What is your use case?

Anthony Williams
+4  A: 

Here's a code cleanliness issue that you will want to be aware of. Say a user inputs the option. So you have some variable Number x which might be One or Two. If you want to call foo(), you will need to do...

if (x == One)
    foo<const char *, One>("asd");
else
    foo<const char *, Two>("asd");

where as, if you used the alternative way (your suggestion number two), you could simply do:

foo<const char *>("asd", x);

Now, if in this function, it would be very beneficial to have those possible branches optimized out, then sure. But otherwise, I think you're just making life difficult for yourself.


Also, on how these methods are different. In the code I have written above, I have referenced three different functions. In the final one, where there is only one template parameter, the code generated for that function will include both code paths, when num == One and when num == Two. The first two templated methods, however, will have been able to remove those branches. It can do this because it will build two different code paths in memory, one for each case.

sharth