Thread: Template query

  1. #1
    Registered User
    Join Date
    Jul 2006
    Posts
    4

    Template query

    Hi,

    I am going through some tutorials on templates and there is one on cplusplus.com that I have been using. It is explaining about class templates and here is the code for one of the examples they have made:

    Code:
    // class templates
    #include <iostream>
    using namespace std;
    
    template <class T>
    class pair {
        T a, b;
      public:
        pair (T first, T second)
          {a=first; b=second;}
        T getmax ();
    };
    
    template <class T>
    T pair<T>::getmax ()
    {
      T retval;
      retval = a>b? a : b;
      return retval;
    }
    
    int main () {
      pair <int> myobject (100, 75);
      cout << myobject.getmax();
      return 0;
    }
    This code looks fine to me and I understand it but when coming to compile this using g++ I get the following errors:

    main.cpp:15: error: expected init-declarator before '<' token
    main.cpp:15: error: expected `;' before '<' token
    main.cpp: In function `int main()':
    main.cpp:23: error: `pair' undeclared (first use this function)
    main.cpp:23: error: (Each undeclared identifier is reported only once
    unction it appears in.)
    main.cpp:23: error: expected primary-expression before "int"
    main.cpp:23: error: expected `;' before "int"
    main.cpp:24: error: `myobject' undeclared (first use this function)


    When I remove the "using namespace std;" statement and use the scope resolution operator to access the cout function of the std namespace in main(); "std::cout << myobject.getmax();" instead of "cout << myobject.getmax();" the code compiles fine.

    Am I missing something? Can anybody tell me why this is happening?


    Thanks

  2. #2
    Registered User
    Join Date
    May 2006
    Posts
    903
    Yes you are missing something. Have we ever told you that 'using namespace std;' is evil ? Well this is why. There is already an STL container named pair in the std namespace.

    This is because the 'using namespace std;' directive makes all of the content of the std nameespace available to the global namespace which clashes with your class pair and std's pair.

  3. #3
    Registered User
    Join Date
    Jul 2006
    Posts
    4
    Thanks Desolation. I am currently looking at another example about Template specialization:

    Code:
    // template specialization
    #include <iostream>
    using namespace std;
    
    template <class T>
    class container {
        T element;
      public:
        container (T arg) {element=arg;}
        T increase () {return ++element;}
    };
    
    template <>
    class container <char> {
        char element;
      public:
        container (T arg) {element=arg;}
        char uppercase ();
    };
    
    template <>
    char container<char>::uppercase()
    {
      if ((element>='a')&&(element<='z'))
      element+='A'-'a';
      return element;
    }
    
    int main () {
      container<int> myint (7);
      container<char> mychar ('j');
      cout << myint.increase() << endl;
      cout << mychar.uppercase() << endl;
      return 0;
    }
    main.cpp:17: error: expected `)' before "arg"
    main.cpp:23: error: template-id `uppercase<>' for `char container<char>::uppercase()' does not match any template declaration
    main.cpp:23: error: invalid function declaration
    main.cpp: In function `int main()':
    main.cpp:31: error: no matching function for call to `container<char>::container
    (char)'
    main.cpp:14: note: candidates are: container<char>::container()
    main.cpp:14: note: container<char>::container(const container<char>&)

    This code also does not compile, any ideas why not?


    Thankyou.

  4. #4
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    my experience with templates is mostly from try and error, so I can't tell you why it works or if this is a special feature of my compiler.
    For me it works like this

    Code:
    // template specialization
    #include <iostream>
    using namespace std;
    
    template <class T>
    class container {
        T element;
      public:
        container (T arg) {element=arg;}
        T increase () {return ++element;}
    };
    
    template <>
    class container <char> {
        char element;
      public:
        container (char arg) {element=arg;}
        char uppercase();
    
    };
    
    //template <>
    char container<char>::uppercase(){
        if ((element>='a')&&(element<='z'))
            element+='A'-'a';
        return element;
    }
    
    int main () {
      container<int> myint (7);
      container<char> mychar ('j');
      cout << myint.increase() << endl;
      cout << mychar.uppercase() << endl;
      return 0;
    }
    Kurt
    Last edited by ZuK; 07-02-2006 at 11:09 AM.

  5. #5
    Registered User
    Join Date
    Jul 2006
    Posts
    4
    Thanks Kurt, that makes sense actually as the template parameter T I had in the char container specialization constructor did not have a valid template declaration beforehand (i.e. template <class T>) so the compiler did'nt know what it belongs to. Also I suppose the "template<>" declaration I had for the template class char specialization member function "uppercase()" did'nt really mean anything as the
    Code:
    char container<char>::uppercase(){
        if ((element>='a')&&(element<='z'))
            element+='A'-'a';
        return element;
    }
    definition itself is enough information for the compiler to determine that the method belonged to the template char specialization class. It seems that for external member function definitions in template specialization classes there is no need to declare the "template<>" definition because the method signature already knows what template parameter to use via the char in:
    Code:
    char container<char>::uppercase(){
        if ((element>='a')&&(element<='z'))
            element+='A'-'a';
        return element;
    }
    Thanks for your help, wonder why cplusplus.com has code that is'nt compilable in its tutorials, very strange.

  6. #6
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    Quote Originally Posted by compsi
    Thanks for your help, wonder why cplusplus.com has code that is'nt compilable in its tutorials, very strange.
    compsi, what compiler are you using? if it's vc6, be aware that visual studio 6 has many problems with compiling template code.
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  7. #7
    Registered User
    Join Date
    Jul 2006
    Posts
    4
    I'm using the GNU g++ compiler within Eclipse using the CDT C++/C plugin. I also tried the above in an external file and compiled using the command line.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. In template function, how query the type?
    By 6tr6tr in forum C++ Programming
    Replies: 24
    Last Post: 04-02-2008, 04:27 PM
  2. Specialising a member function with a template template parameter
    By the4thamigo_uk in forum C++ Programming
    Replies: 10
    Last Post: 10-12-2007, 04:37 AM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. error: template with C linkage
    By michaels-r in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2006, 08:11 AM
  5. oh me oh my hash maps up the wazoo
    By DarkDays in forum C++ Programming
    Replies: 5
    Last Post: 11-30-2001, 12:54 PM