I have been given a small topic to write on which is
We can not use Templates in every situation, there are only some specific situations where they should be used.
Please give me some hints that in which situations we should not use them.
Thanks
Printable View
I have been given a small topic to write on which is
We can not use Templates in every situation, there are only some specific situations where they should be used.
Please give me some hints that in which situations we should not use them.
Thanks
Read Stroustrup's answer to the FAQ: What is "generic programming" and what's so great about it?
In particular, the last sentence of that FAQ item provides some balance that is a starting point for an answer to your question.
That's asking the wrong question. Templates have a specific purpose (see laserlight's link) and should be used in situations that benefit from this. Asking for example of where they shouldn't be used is not appropriate - they shouldn't be used in all the places where the reasons to use them do not apply, or are trumped by the reasons to use some other feature (some other polymorphism form of C++) instead.Quote:
Please give me some hints that in which situations we should not use them.
My personal experience is that it takes much longer to code using templates, and it can be confusing and arcane in some cases due to the myriads of hidden default rules. I would only use them if performance was critical (e.g. hardwiring class parameters at compile time) or if you are absolutely sure you need to reuse classes and algorithms for multiple types.
If you do use them, it is often better to write the special case first, debug it completely and then generalize the parameters you need via templates. It's much more pleasant to use templates than to write them, so make heavy use of the STL. Most of the standard computer science data structures and algorithms can be found there.
In fact I might go a bit further. C++ is most productive if you restrict yourself to a very controlled subset of the language that reuses existing components. Once you have to start writing more complex classes that require things like (for example) overriding the destructor, assignment operator and copy constructor, (ie you are managing raw memory), it gets very tedious, especially if the class is in a template. In fact I'd almost prefer to use a garbage collector under the latter conditions. It's a lot more productive, though it's not considered proper C++ style.
This is even crazier than asking when you shouldn't use inheritance.
++Quote:
Templates have a specific purpose (see laserlight's link) and should be used in situations that benefit from this. Asking for example of where they shouldn't be used is not appropriate - they shouldn't be used in all the places where the reasons to use them do not apply, or are trumped by the reasons to use some other feature (some other polymorphism form of C++) instead.
This may be true for simple template applications. It is simply backwards, or even impossible, for many advanced applications.Quote:
If you do use them, it is often better to write the special case first, debug it completely and then generalize the parameters you need via templates.
Any language is more "productive" if you reuse existing code. It takes time to recreate something that already exists. This isn't unique to C++, templates, or even programming.Quote:
C++ is most productive if you restrict yourself to a very controlled subset of the language that reuses existing components.
The notion that using only a subset of the language is somehow more "productive" is bogus. Any subset you may wish to define necessarily excludes something that will be more suitable in a given context than what is available to the subset.
This too is bogus. A simple template class, like most of the STL, isn't more or less difficult to write than a single instance of the class--as if specialized for one of the target types expected for use in parametrization.Quote:
Once you have to start writing more complex classes that require things like (for example) overriding the destructor, assignment operator and copy constructor, (ie you are managing raw memory), it gets very tedious, especially if the class is in a template.
Soma
I would also say take a look at Vandevoorde and Josuttis' "C++ Templates, The Complete Guide". There are a large number of examples of when TO use Templates, and of course hoe to implement them.
Cheers!
I'll have to disagree and in fact I'll give you a nice little head scratcher to prove my point. (I haven't check the example code for syntax so bear with me.)Quote:
This too is bogus. A simple template class, like most of the STL, isn't more or less difficult to write than a single instance of the class--as if specialized for one of the target types expected for use in parametrization
Here is a class that uses a generic type and array size.
Code:
template<typename T, int size>
class MyClass {
public:
T arr[size] ;
// default constructor
MyClass {} ;
// copy constructor
MyClass(const MyClass &mc)
{
int i ;
for (i = 0 ; i < size ; i++) {
arr[i] = mc[i] ; // assumes copy assignment exists for T
}
}
// similarly define copy assignment operator etc....
} ;
OK now how do you make templated copy and/or assignment operators that convert between different types and different sizes? Assume that a small size can convert to a bigger size via zero padding or that a big size can convert to a smaller via truncation. Assume also that there is a natural conversion between types T via a constructor perhaps or via typecasting.
This sort of problem is common enough for interesting uses of templating, but it requires covering a bunch of special cases and somewhat arcane syntax. If you do provide a solution take note of how long it took you to find the reference or design pattern that does the job. (I know some of the experts will know how to do this right away, but I suspect the casual C++ user will struggle a little at first).
I have no idea what you're talking about. Either you want the natural behavior of the types, in which case the templated "foreign instantiation conversion constructor" has the same implementation as the copy constructor, or you want to customize conversion for every type, in which case you need a simple traits class - not hard to design or implement, and out of the scope of the comparison with a concrete class, where the problem of conversion from a different instantiation simply doesn't occur.
The point is that this conversion exercise is messy but a common issue with templates. It requires some unusual syntax to get to work properly and proves my point that writing templated code is a non-trivial exercise. Expect the write and debug time to be longer than for normal code. The latter is hardly a controversial statement. I just provided one example where things can get messy, though it is useful. See for example this templated version of dimensional analysis:
http://www.ddj.com/architect/184401579
http://learningcppisfun.blogspot.com...templates.html
I still don't see a point. The contented (contended?) issue comes from your post where you say:
You've made the claim that a template with equal functionality as a concrete class (plus generality) is harder to write. phantomatap disagrees. You counter with examples of templates that add things beyond what a concrete class is capable of. You're simply not supporting your position this way.Quote:
My personal experience is that it takes much longer to code using templates [...]
If you do use them, it is often better to write the special case first, debug it completely and then generalize the parameters you need via templates.[...]
Once you have to start writing more complex classes that require things like (for example) overriding the destructor, assignment operator and copy constructor, (ie you are managing raw memory), it gets very tedious, especially if the class is in a template.[...]
It all depends on your perspective. I agree with your statement if all you are doing is trying to provide a little bit of type generality. However IMHO the interesting applications of templates involve the sort of conversion issues and thus the complexities I'm warning about.
In particular if you want to hardwire parameters at compile time for performance reasons, then you will typically need to write a mess of conversion functions via whatever trickery you care to use - whether you use heavily parameterized function templates or intermediate template classes that define parameterized types. (Is that what traits do?)
Is that what you mean?
(Incomplete and untested.)Code:#include <algorithm>
template <class T, unsigned size>
class X
{
T array[size];
public:
X()
{
std::fill(array, array + size, T());
}
template <class U, unsigned size_b>
X(const X<U, size_b>& x)
{
*this = x;
}
template <class U, unsigned size_b>
const X& operator=(const X<U, size_b>& x)
{
std::copy(x.array, x.array + std::min(size, size_b), array);
std::fill(array + std::min(size, size_b), array + size, T());
return *this;
}
template <class U, unsigned size_b>
friend class X;
};
Well heck, that's a lot nicer than what I was thinking of. I thought you would have to declare a bunch of separate function templates outside the main class definition which tends to proliferate the required declarations.
I'm actually glad I posted this. I think I tried to initially declare my generalized templated operators inside the class but was having trouble getting them instantiated properly. Your code compiles and seems to be doing the correct thing after checking with my debugger.
I used double for the type. I guess double has a default initializer? Also will std::copy use the copy constructor or perhaps copy assignment for the classes?
The T() syntax results in value initialisation, and value initialisation for double means zero initialisation.Quote:
Originally Posted by SevenThunders
It might use either, or it might not. In this case it probably uses copy assignment, but then copy assignment can involve copy construction.Quote:
Originally Posted by SevenThunders
Next up -- a 500 word essay describing the situations in which one should NOT use a pitchfork. Due by EOD next Friday. Please be complete.
O_oQuote:
OK now how do you [...] or via typecasting.
This could not be done without templates. The best you could hope for is supporting a subset of the possibilities. Trying to do this would be tedious in the extreme. How is this supporting your claim that "templates are especially tedious"?
The interesting applications of templates involves interface and implementation generation of arbitrarily many distinct classes from arbitrarily many building blocks. This is tedious. It can't be done without templates. This is not what you've compared to normal classes. The next C++ standard will greatly simplify this sort of thing with variadic templates and new reference types. Rejoice!Quote:
However [...] complexities I'm warning about.
I'm not sure what you are asking. I think type lists and simple forwarding will get you what you want. If you want to ask more about this start a new thread.Quote:
In particular if you want to hardwire [...] parameterized types.
Traits store arbitrary interface and implementation guidelines according to some expected interface as specified by the target type that other templates then use to determine their interface and implementation.
Policies are similar in that they store arbitrary interface and implementation guidelines. They differ in that they have nothing to do with the target type. Policies are utilized to provide a choice between differing interface and implementation guidelines targeted solely to the programmers discretion.
Soma