Please help me in this theoretical question of C++ Templates

This is a discussion on Please help me in this theoretical question of C++ Templates within the C++ Programming forums, part of the General Programming Boards category; I have been given a small topic to write on which is We can not use Templates in every situation, ...

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    1

    Please help me in this theoretical question of C++ Templates

    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

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    20,980
    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.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,892
    Please give me some hints that in which situations we should not use them.
    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.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  4. #4
    Registered User
    Join Date
    Apr 2007
    Posts
    129
    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.

  5. #5
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    3,831
    This is even crazier than asking when you shouldn't use inheritance.

    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.
    ++

    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.
    This may be true for simple template applications. It is simply backwards, or even impossible, for many advanced applications.

    C++ is most productive if you restrict yourself to a very controlled subset of the language that reuses existing components.
    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.

    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.

    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.
    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.

    Soma

  6. #6
    Registered User
    Join Date
    Dec 2008
    Posts
    65
    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!

  7. #7
    Registered User
    Join Date
    Apr 2007
    Posts
    129
    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
    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.)

    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).

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,892
    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.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Registered User
    Join Date
    Apr 2007
    Posts
    129
    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

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,892
    I still don't see a point. The contented (contended?) issue comes from your post where you say:

    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.[...]
    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.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Registered User
    Join Date
    Apr 2007
    Posts
    129
    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?)

  12. #12
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Is that what you mean?

    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;
    };
    (Incomplete and untested.)
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  13. #13
    Registered User
    Join Date
    Apr 2007
    Posts
    129
    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?

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    20,980
    Quote Originally Posted by SevenThunders
    I used double for the type. I guess double has a default initializer?
    The T() syntax results in value initialisation, and value initialisation for double means zero initialisation.

    Quote Originally Posted by SevenThunders
    Also will std::copy use the copy constructor or perhaps copy assignment for the classes?
    It might use either, or it might not. In this case it probably uses copy assignment, but then copy assignment can involve copy construction.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,160
    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.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Design layer question
    By mdoland in forum C# Programming
    Replies: 0
    Last Post: 10-19-2007, 04:22 AM
  2. Templates question
    By tezcatlipooca in forum C++ Programming
    Replies: 9
    Last Post: 12-30-2006, 01:08 PM
  3. opengl DC question
    By SAMSAM in forum Game Programming
    Replies: 6
    Last Post: 02-26-2003, 08:22 PM
  4. Stack Question With Templates
    By Anonymous Freak in forum C++ Programming
    Replies: 6
    Last Post: 02-09-2003, 11:18 AM
  5. newbie class templates question
    By daysleeper in forum C++ Programming
    Replies: 2
    Last Post: 09-18-2001, 09:50 AM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21