CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 3 123 LastLast
Results 1 to 15 of 34
  1. #1
    Join Date
    Mar 2007
    Posts
    45

    C++ Templates: The Complete Guide

    Hello,

    I purchased this book hoping to gain a further understanding in templates. But my issue is that, a lot of the code that the book says WONT compile, ... does. Such as the following -

    Code:
    // maximum of two values of any type
    template <typename T>
    inline T const& max (T const& a, T const& b)
    {
        return  a < b ? b : a;
    }
    
    // maximum of three values of any type
    template <typename T>
    inline T const& max (T const& a, T const& b, T const& c)
    {
        return max (max(a,b), c);  // uses the template version even for ints
    }                              // because the following declaration comes
                                   // too late:
    // maximum of two int values
    inline int const& max (int const& a, int const& b) 
    {
        return  a < b ? b : a;
    }
    Which calls the int function for me on VS2008, CodeBlocks and DevC++. Where i had the latter 2 set to the GCC compiler. Other issues are examples where although the book says i need to use typename for some dependant type, VS2008 doesnt require it.

    Im not sure if this is due to the book being out of date or what. But i was wondering if you could give me some advice as to how i should continue. Should i keep reading? is there some other more up to date material that these compilers are conforming too?


    thanks

  2. #2
    Join Date
    Nov 2006
    Posts
    1,611

    Re: C++ Templates: The Complete Guide

    I'm using VS2008 also, and I have experience but don't have handy GCC of various versions.

    In my own work I've seen there are differences between these two compilers regarding the tolerance of the order of appearance for template classes and functions. VS2008 is the less restrictive. Code which VS2008 compiles might cause GCC to complain, but to date I've found that when GCC accepts it, VS2008 has no problem.

    I haven't tried this since 3.x, since I always took some care in this regard, but if your code were:

    Code:
    // maximum of three values of any type
    template <typename T>
    inline T const& max (T const& a, T const& b, T const& c)
    {
        return max (max(a,b), c);  // uses the template version even for ints
    }                              // because the following declaration comes
                                   // too late:
    
    
    // maximum of two values of any type
    template <typename T>
    inline T const& max (T const& a, T const& b)
    {
        return  a < b ? b : a;
    }
    I might expect VS2008 to accept this (and it did), but GCC might not.

    This, on the other hand

    Code:
    // maximum of two values of any type
    template <typename T>
    inline T const& max (T const& a, T const& b)
    {
        return  a < b ? b : a;
    }
    
    // maximum of three values of any type
    template <typename T>
    inline T const& max (T const& a, T const& b, T const& c)
    {
        return max (max(a,b), c);  // uses the template version even for ints
    }                              // because the following declaration comes
                                   // too late:
    Is likely to pass both compilers just fine.

    Since the template max with two parameters also does what the int version in your code does, I'd expect the illustration would not fail at all.


    To your broader question, while I don't know the book you're using, if it's published after 2004 it's probably relevant. Heck, if it was current with C++ as of 1999 it may be relevant, but offer the caveat that a compiler like VC6 (which was still the Visual Studio version of that day) might have a lot more trouble than any of the recent versions.
    If my post was interesting or helpful, perhaps you would consider clicking the 'rate this post' to let me know (middle icon of the group in the upper right of the post).

  3. #3
    Join Date
    Jan 2008
    Location
    California, USA
    Posts
    822

    Re: C++ Templates: The Complete Guide

    Hm when you say
    Quote Originally Posted by wheelie View Post
    Hello,

    I purchased this book hoping to gain a further understanding in templates. But my issue is that, a lot of the code that the book says WONT compile, ... does. Such as the following -
    and go on to say
    Which calls the int function for me on VS2008, CodeBlocks and DevC++.
    what are you trying to say?
    Are you saying that you'd get a compilation error compiling just the code,
    or when you actually try to call the function?
    Either way, be more specific in what you're trying to do so that we can understand the problem better.
    Other issues are examples where although the book says i need to use typename for some dependant type, VS2008 doesnt require it.
    what do you mean?

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: C++ Templates: The Complete Guide

    Which calls the int function for me on VS2008
    Template code needs to be called and/or instantiated first before concluding the code compiles or not. I see no instantiation of any templates or calls to the template functions in the code that you posted. Many compilers will not compile template code unless the template code is actually being called -- instead the compiler will indicate that there are "no errors", giving you the feeling that the template code is OK (when it could be riddled with compiler errors).

    Secondly, just because a compiler may compile some code doesn't mean the compiler is right and the authors are wrong..
    Other issues are examples where although the book says i need to use typename for some dependant type, VS2008 doesnt require it.
    That doesn't mean that VS2008 is correct. VC 6.0 never required "typename" at all. It doesn't mean it is correct.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; July 13th, 2009 at 03:46 AM.

  5. #5
    Join Date
    Mar 2007
    Posts
    45

    Re: C++ Templates: The Complete Guide

    Sorry guys, i do apologise, bad wording on my part. What i meant to say was that the code does compile, but when instantiated, doesn't behave as described by the authors.

    Concerning the above code, which can be found on the authors site Here

    When compiled as follows, it does seem to call the int function which the authors say it wont.

    Code:
    #include <iostream>
    using namespace std;
    
    // maximum of two values of any type
    template <typename T>
    inline T const& max (T const& a, T const& b)
    {
    	cout << "inline T const& max (T const& a, T const& b)" << endl;
        return  a < b ? b : a;
    }
    
    // maximum of three values of any type
    template <typename T>
    inline T const& max (T const& a, T const& b, T const& c)
    {
    	cout << "inline T const& max (T const& a, T const& b, T const& c)" << endl;
        return max (max(a,b), c);  // uses the template version even for ints
    }                              // because the following declaration comes
                                   // too late:
    // maximum of two int values
    inline int const& max (int const& a, int const& b) 
    {
    	cout << "inline int const& max (int const& a, int const& b)" << endl;
        return  a < b ? b : a;
    }
    
    int main()
    {
        int a, b, c;
    	a = 1; b = 2; c = 3;
    	max(a,b,c);
    	getchar();
        return 0;
    }

    And for my example of typenames, i was meaning this sort of situation, where the authors mention that using the keyword typename is required for dependant types, to specify that they are indeed an actual type rather than some member.
    Yet works fine without it.

    Code:
    class A
    {
    public:
    	typedef int IntType;
    };
    
    template < typename T >
    void Func( T t )
    {
    	/* typname */ T::IntType i = 6;  //book specifies that the keyword is required
    	cout << i ;
    }
    
    
    int main()
    {
        A a;
    	Func(a);
    	getchar();
        return 0;
    }

    Secondly, just because a compiler may compile some code doesn't mean the compiler is right and the authors are wrong..
    I wasnt trying to say that, im simply asking how i can study a subject that doesnt seem to behave as books on the subject say it is suppose too. Whether it be due to the compiler not conforming or not, it makes it difficult to experiment when things go differetly to the training material.

    How have you guys been learning it?
    Last edited by wheelie; July 13th, 2009 at 08:06 AM.

  6. #6
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: C++ Templates: The Complete Guide

    Quote Originally Posted by wheelie
    im simply asking how i can study a subject that doesnt seem to behave as books on the subject say it is suppose too. Whether it be due to the compiler not conforming or not, it makes it difficult to experiment when things go differetly to the training material.
    You can try disabling language extensions and setting the warning level to the maximum. You can also compile your test programs with another compiler (e.g., the MinGW port of GCC and/or the Comeau online compiler) to see if there is a difference.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  7. #7
    Join Date
    Mar 2008
    Posts
    38

    Re: C++ Templates: The Complete Guide

    Quote Originally Posted by wheelie View Post
    Hello,

    I purchased this book hoping to gain a further understanding in templates. But my issue is that, a lot of the code that the book says WONT compile, ... does. Such as the following -

    Code:
    // maximum of two values of any type
    template <typename T>
    inline T const& max (T const& a, T const& b)
    {
        return  a < b ? b : a;
    }
    
    // maximum of three values of any type
    template <typename T>
    inline T const& max (T const& a, T const& b, T const& c)
    {
        return max (max(a,b), c);  // uses the template version even for ints
    }                              // because the following declaration comes
                                   // too late:
    // maximum of two int values
    inline int const& max (int const& a, int const& b) 
    {
        return  a < b ? b : a;
    }
    Which calls the int function for me on VS2008, CodeBlocks and DevC++. Where i had the latter 2 set to the GCC compiler. Other issues are examples where although the book says i need to use typename for some dependant type, VS2008 doesnt require it.

    Im not sure if this is due to the book being out of date or what. But i was wondering if you could give me some advice as to how i should continue. Should i keep reading? is there some other more up to date material that these compilers are conforming too?


    thanks
    I think you should use whatever compiler the book recommends. If it doesn't recommend any, then find a book that does. In my experience, visual has a lot of unique quirks that are learned with experience. If that makes it tough for you to learn something new, then use a different compiler when learning a new topic.

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: C++ Templates: The Complete Guide

    Quote Originally Posted by wheelie View Post
    Sorry guys, i do apologise, bad wording on my part. What i meant to say was that the code does compile...
    Here is what the Comeau on-line compiler has to say about this code:
    Code:
    Thank you for testing your code with Comeau C/C++!
    Tell others about http://www.comeaucomputing.com/tryitout ! 
    
    Your Comeau C/C++ test results are as follows: 
    
    
    Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
    Copyright 1988-2008 Comeau Computing.  All rights reserved.
    MODE:strict errors C++ C++0x_extensions
    
    "ComeauTest.c", line 17: error: more than one instance of overloaded function "max"
              matches the argument list, the choices that match are:
                function template "const T &max(const T &, const T &)"
                function template "const _Tp &std::max(const _Tp &, const _Tp &)"
                The argument types that you used are: (const int, const int)
          return max (max(a,b), c);  // uses the template version even for ints
                      ^
              detected during instantiation of "const T &max(const T &, const T &,
                        const T &) [with T=int]" at line 31
    
    "ComeauTest.c", line 17: error: no instance of overloaded function "max" matches the
              argument list
                The argument types that you used are: (<error-type>, const int)
          return max (max(a,b), c);  // uses the template version even for ints
                 ^
              detected during instantiation of "const T &max(const T &, const T &,
                        const T &) [with T=int]" at line 31
    
    2 errors detected in the compilation of "ComeauTest.c".
    
    In strict mode, with -tused, Compile failed
    So it doesn't compile wth the Comeau compiler, and Comeau is one of, if not, the most compliant ANSI C++ compiler out there. In addition, your original code you posted did "compile" OK using the Comeau compiler -- this stresses my point that template code must be instantiated somewhere before it can be verified that the code compiles fine or not.

    I would believe the book. The authors of the book (Josuttis and Vandevoorde) are two expert C++ programmers who actually study compliancy, language rules, etc. It isn't easy just to dismiss their books. If there is an error, an errata would have been posted (as Josuttis has done with his other book "The C++ Standard Library").

    Also, for g++ turn off all the language extensions and compile using the ANSI mode. If you don't do that, even this compiles correctly:
    Code:
    int main()
    {
        int n = 10;
        int array[n];  // This is an error, but g++ compiles this if you do not turn on the ANSI mode.
    }
    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; July 13th, 2009 at 08:56 AM.

  9. #9
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: C++ Templates: The Complete Guide

    I have just tested the following code with both VS and GCC:

    Code:
    #include <iostream>
    
    // maximum of two values of any type
    template <typename T>
    inline T const& max (T const& a, T const& b)
    {
      std::cout << "T const& max (T const& a, T const& b)" << std::endl;
        return  a < b ? b : a;
    }
    
    // maximum of three values of any type
    template <typename T>
    inline T const& max (T const& a, T const& b, T const& c)
    {
      std::cout << "T const& max (T const& a, T const& b, T const& c)" << std::endl;
      return max (max(a,b), c);  // uses the template version even for ints
    }                              // because the following declaration comes
                                   // too late:
    // maximum of two int values
    inline int const& max (int const& a, int const& b) 
    {
      std::cout << "int const& max (int const& a, int const& b) " << std::endl;
      return  a < b ? b : a;
    }
    
    int main()
    {
      int a(0);
      int b(0);
      int c(0);
    
      std::cout << max(a,b,c) << std::endl;
    
      std::cin.get();
    }
    GCC generates the expected result:
    T const& max (T const& a, T const& b, T const& c)
    T const& max (T const& a, T const& b)
    T const& max (T const& a, T const& b)
    0
    But VS2008 generates the following output (with and without language extensions disabled)
    T const& max (T const& a, T const& b, T const& c)
    int const& max (int const& a, int const& b)
    int const& max (int const& a, int const& b)
    0
    I must admit, I find this behavior concerning.

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: C++ Templates: The Complete Guide

    Quote Originally Posted by PredicateNormative View Post
    I have just tested the following code with both VS and GCC:
    You're testing code that, according to Comeau (and the book in question), shouldn't even exist. Therefore if you produced an executable from code that is invalid, anything can happen.

    Regards,

    Paul McKenzie

  11. #11
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: C++ Templates: The Complete Guide

    When I paste PredicateNormative's code into Comeau it gives...

    In strict mode, with -tused, Compile succeeded (but remember, the Comeau online compiler does not link).
    Compiled with C++0x extensions enabled.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  12. #12
    Join Date
    Apr 1999
    Posts
    27,449

    Re: C++ Templates: The Complete Guide

    Quote Originally Posted by JohnW@Wessex View Post
    When I paste PredicateNormative's code into Comeau it gives...

    In strict mode, with -tused, Compile succeeded (but remember, the Comeau online compiler does not link).
    Compiled with C++0x extensions enabled.
    My mistake. I thought that the OP's new code was being tested.

    Regards,

    Paul Mckenzie

  13. #13
    Join Date
    Nov 2006
    Posts
    1,611

    Re: C++ Templates: The Complete Guide

    This puzzle is intriguing.

    From a logical perspective, aside from C++ standards documentation, this code does present a seeming conundrum.

    We have max in a "standard" function operating on int, and a comparable template function max for any type, which logically conflict (though these examples do the same thing) when T is int.

    I would expect the compiler to favor the "standard" max for int, rather than generate a template - because the application code has called max on int for which there's no need to search for a solution by generating the template.

    For other types, obviously, the function max wouldn't be found unless the template were generated.

    Why, then, would any compiler (or the standard) result in logic where the template would be generated when a suitable function is already fully defined to satisfy the call?

    To that end, the visual studio result SEEMS reasonable, even if it violates the standard.

    Now, not having read the book, I would view this example of a subtle logical error in programming - an alias, if you will, of the max function which could be satisfied by two approaches, creating a logical conundrum which would need either an arbitrary solution, or rejection because of the paradox. I can see why the compiler might not reject the two versions of max (the name mangled identifiers are different), while the ambiguity at the point of the call to max can be logically satisfied by choosing to avoid the extra work of generating a template when the call can be satisfied, something like we'd expect from a template specialization (which can't be done with functions).

    I think it's an example of what not to do, but I must admit I find it disconcerting that VS simply makes a choice and goes right on.

    Indeed, with language extensions off, warnings at 4 and code analysis turned on, all VS complains about are unreferenced formal parameters.

    If the function in question were not max, but any function, and the code for the template and non-template versions were entirely unrelated (as in this happened because of a real oversight in development), the results would be compiler dependent, give no warning, and it could be quite a subtle bug which I've never considered before (commonly using the VS compiler as I do).

    Fortunately I build cross platform stuff, and typically do check with other compilers, but here's another interesting difference among them.
    If my post was interesting or helpful, perhaps you would consider clicking the 'rate this post' to let me know (middle icon of the group in the upper right of the post).

  14. #14
    Join Date
    Jan 2008
    Location
    California, USA
    Posts
    822

    Re: C++ Templates: The Complete Guide

    First and foremost, let's not forget we already have max function in our standard namespace.
    OP's code fails on Comeau, GCC (minGW port), but compiles on VS2008 (with warning lv4, and extension disabled)
    PredicateNormative's code compiles on all three.
    The difference is that OP uses using directive while PredicateNormative qualifies a full name
    (effectively eliminating name collision).
    So the problem stems from the name collision and confuses the compiler in finding best match.

    @wheelie:
    Notice how Josuttis doesn't use "using namespace std", but you do.
    when you introduce std namespace at a global scope, take precaution,
    especially when you design classes/functions that are so commonly used by other developers.

    Designing a set of overloads involving template and non-templates is tricky (and hard)
    especially when the the types of arguments are closely related by conversion.
    You need to understand function matching thoroughly,
    and need to know where and at what stage(s) of overload resolution the ambigous call can occur
    Code:
    class A
    {
    public:
    	typedef int IntType;
    };
    
    template < typename T >
    void Func( T t )
    {
    	/* typname */ T::IntType i = 6;  //book specifies that the keyword is required
    	cout << i ;
    }
    
    
    int main()
    {
        A a;
    	Func(a);
    
        return 0;
    }
    this fails to compile on all three, so I thnk Josuttis is correct.

    Last but not the least,
    prefer a set of template specialization over overloading a set of template and non-template combined.
    Last edited by potatoCode; July 13th, 2009 at 02:14 PM. Reason: fixed some spelling error xD

  15. #15
    Join Date
    Mar 2007
    Posts
    45

    Re: C++ Templates: The Complete Guide




    So the problem stems from the name collision and confuses the compiler in finding best match.

    @wheelie:
    Notice how Josuttis doesn't use "using namespace std", but you do.
    when you introduce std namespace at a global scope, take precaution,
    especially when you design classes/functions that are so commonly used by other developers.
    It still gives me the same result in vs2008

    inline T const& max (T const& a, T const& b, T const& c)
    inline int const& max (int const& a, int const& b)
    inline int const& max (int const& a, int const& b)
    Press any key to continue . . .



    Code:
    #include <iostream>
    
    // maximum of two values of any type
    template <typename T>
    inline T const& max (T const& a, T const& b)
    {
    	std::cout << "inline T const& max (T const& a, T const& b)" << std::endl;
        return  a < b ? b : a;
    }
    
    // maximum of three values of any type
    template <typename T>
    inline T const& max (T const& a, T const& b, T const& c)
    {
    	std::cout << "inline T const& max (T const& a, T const& b, T const& c)" << std::endl;
        return max (max(a,b), c);  // uses the template version even for ints
    }                              // because the following declaration comes
                                   // too late:
    // maximum of two int values
    inline int const& max (int const& a, int const& b) 
    {
    	std::cout << "inline int const& max (int const& a, int const& b)" << std::endl;
        return  a < b ? b : a;
    }
    
    int main()
    {
        int a, b, c;
    	a = 1; b = 2; c = 3;
    	max(a,b,c);
    	getchar();
        return 0;
    }

    Also, are you saying that the following didnt compile for you in VS2008? It still compiles for me, only with warnings, with lvl4 and extensions disabled

    Code:
    #include <iostream>
    class A
    {
    public:
    	typedef int IntType;
    };
    
    template < typename T >
    void Func( T t )
    {
    	/* typname */ T::IntType i = 6;  //book specifies that the keyword is required
    	std::cout << i ;
    }
    
    
    int main()
    {
        A a;
    	Func(a);
    
        return 0;
    }
    Last edited by wheelie; July 14th, 2009 at 12:35 AM.

Page 1 of 3 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured