# which is better: template or constructor parameters?

This topic is 4974 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Which of the following is better (ie memory and speed trade-offs) Snippet 1 - using template parameter to pass a value
template <class T, T value>
struct ByTemplate
{
vector<T> block;

ByTemplate () : block(20, value) { }
void MakeDefault (int pos) { block[pos] = value; }
};
---------- Snippet 2 - using constructor paramater to pass a value
template <class T>
struct ByConstructor
{
vector<T> block;
T value;

ByConstructor (T cVal) : value(cVal), block(20, value) { }
void MakeDefault (int pos) { block[pos] = value; }
};
This is just dummy code, what I actually want to do is keep a copy of T around for in-place construction, but the above does show what I;m asking. I think that Snippet1 is faster because value is around at compile time so it might allow optmizations to take place, it might also be better from the point of view that I don't have to store it within the class (as in Snippet2) but I'm not sure if the compiler would do this anyway (so no memory saved). wot does anyone think? Thanx in advance :)

##### Share on other sites
That doesn't seem like a performance bottleneck, not by a long shot, so the *much* greater flexibility offered by the constructor way would seem to be a better solution. Without knowing more about what the code is meant to do, it is hard to give any generally applicable advice.

If you are absolutely sure that a compile-time constant is enough now and in the future (refactoring afterwards will likely be a big pain in the butt), you could go the template way and use the constant-length array class from boost::array. But if you are even a bit unsure about the level of flexibility you might someday require, I'd recommend the more dynamic way.

##### Share on other sites
i don't really see any advantage to snippet 2 unless you won't know what value you want until runtime.

##### Share on other sites
Quote:
 Original post by dmatterwot does anyone think?Thanx in advance :)

I think that this is probably a horrible micro-optimization that will provide no noticeable speed benifit after much wasted time.

That said, which one is faster will depend entirely on wheither or not you're using a lot of different values or not. If you're only using one value, at worst, the first version won't be any slower. If you're using many values, the first version could be much slower due to the fact that a new version of each function will be created on most compilers for each value, causing more page misses and so forth when calling the function. That said, I suspect they will likely both preform EXACTLY the same and compile into the EXACT same code (in release mode, disregarding the symbol information), the constructor and so forth completely inlined to calls to vector.

In any case, the only definitive answer is to try both of them in a real life example (not some pansy ass benchmark, I'm talking about plug it in to your existing code that's having preformance problems in this area - if you don't have such code, you're prematurely optimizing, which is a waste of your time) and compare. When you can't tell a difference between the two, you'll know you've been wasting your time :-).

As such, I'd make my pick based on flexibility/what I wanted to do. Unless I'm doing some major template meta-programming, this would mean snippet 2 is best, since you can choose the value at runtime.

[Edited by - MaulingMonkey on June 9, 2005 3:39:37 PM]

##### Share on other sites
One problem with the template solution is that you will end up with different classes. For example, the first sample does not compile, but the second does.
    ByTemplate< int, 1 > a;    ByTemplate< int, 2 > b;    a = b;                          // Oops!    ByTemplate< int, 1 > * p = &b;  // Oops!    ByConstructor< int > a( 1 );    ByConstructor< int > b( 2 );    a = b;                          // Ok    ByConstructor< int > * p = &b;  // Ok

In the end, the real question is this: Does the value of 'value' change the behavior of the class? If so, then you want separate classes, so it should be a template parameter. If not, it is just data and should not be a template parameter.

##### Share on other sites
John,

Good observation and nicely worded. A+.

##### Share on other sites
Quote:
 Original post by JohnBoltonOne problem with the template solution is that you will end up with different classes. For example, the first sample does not compile, but the second does. ByTemplate< int, 1 > a; ByTemplate< int, 2 > b; a = b; // Oops! ByTemplate< int, 1 > * p = &b; // Oops! ByConstructor< int > a( 1 ); ByConstructor< int > b( 2 ); a = b; // Ok ByConstructor< int > * p = &b; // OkIn the end, the real question is this: Does the value of 'value' change the behavior of the class? If so, then you want separate classes, so it should be a template parameter. If not, it is just data and should not be a template parameter.

template <class T, T value>struct ByTemplate{    vector<T> block;    ByTemplate () : block(20, value) { }    void MakeDefault (int pos) { block[pos] = value; }    vector< T > & value () { return block; }    const vector< T > & value () const { return block; }    operator vector< T > ( ) { return block; }};

##### Share on other sites
Quote:
Original post by mgarriss
Quote:
 Original post by JohnBoltonOne problem with the template solution is that you will end up with different classes. For example, the first sample does not compile, but the second does. ByTemplate< int, 1 > a; ByTemplate< int, 2 > b; a = b; // Oops! ByTemplate< int, 1 > * p = &b; // Oops! ByConstructor< int > a( 1 ); ByConstructor< int > b( 2 ); a = b; // Ok ByConstructor< int > * p = &b; // OkIn the end, the real question is this: Does the value of 'value' change the behavior of the class? If so, then you want separate classes, so it should be a template parameter. If not, it is just data and should not be a template parameter.

template <class T, T value>struct ByTemplate{    vector<T> block;    ByTemplate () : block(20, value) { }    void MakeDefault (int pos) { block[pos] = value; }    vector< T > & value () { return block; }    const vector< T > & value () const { return block; }    operator vector< T > ( ) { return block; }};

You frogot to add a constructor so ByTemplate will be able to construct from such a vector. Even such a constructor will still not solve the p = &b case. The fact that you can do this also underscores the fact that the behavior dosn't really change the behavior of the class on a structural scale at all.

##### Share on other sites
Quote:
 Original post by MaulingMonkeyYou frogot to add a constructor so ByTemplate will be able to construct from such a vector. Even such a constructor will still not solve the p = &b case. The fact that you can do this also underscores the fact that the behavior dosn't really change the behavior of the class on a structural scale at all.

good points.

_ugly

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 31
• 16
• 11
• 10
• 12
• ### Forum Statistics

• Total Topics
634117
• Total Posts
3015601
×