templates, scope resolution and g++

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • JonathanS
    New Member
    • Jan 2008
    • 37

    templates, scope resolution and g++

    I have some code (a doubly-linked list implemented as a template) which is generating some bizarre errors.

    On Digital Mars C++ (v. 8.42) the code compiles but I have to add what seems to be a superfluous template <typename T> right before the declaration of a friend function to overload <<.

    Code:
    	template <typename T>
    		friend std::ostream & operator<<(std::ostream & os, 
    		const DLink2<T> * dlink);
    In gcc (via mingw, v.3.4.2), the compiler "suggests" putting a <> after the name of the function to suppress a warning (which seems to cause more trouble). In addition to that I get the following error message.

    Code:
    template <typename T>
    DLink2<T>::Node * DLink2<T>::Link(Node * lastlink,T value,bool before)
    error: expected constructor, destructor, or type conversion before '*' token


    Node is a private class within the DLink2 class.

    Code:
    class DLink2
    {
    	
    	private:
    	class Node
    	{	
    		private:
    			Node * _pNext;
    			Node * _pPrev;
            		T    data;
                      ........etc.

    My questions are: I know that gcc and derivatives are more ISO compliant, but what is it about what I was doing that made a difference? And, is there a way to further resolve the scope for the function definition to recognize the Node type as a return type?
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    You might post more of your code. I can't tell if the class DLink2 is a template or not. If it's not the T in private Node class can't be resolved.

    Comment

    • JonathanS
      New Member
      • Jan 2008
      • 37

      #3
      class declaration

      Code:
      #include <iostream>
      template<typename T>
      class DLink2
      {
      	
      	private:
      	class Node
      	{	
      		private:
      			Node * _pNext;
      			Node * _pPrev;
              		T    data;	
      	
      		public:
      			Node(T input) {this->data = input;}
      			Node(){this->data = 0;}
      			Node * getNext() {return this->_pNext;}
      			Node * getPrev() {return this->_pPrev;}
      			void setNext(Node * nextNode) 
      					{this->_pNext = nextNode;}
      			void setPrev(Node * prevNode) 
      					{this->_pPrev = prevNode;}
      			T getData() {return this->data;}
      			void setData(T value){this->data = value;}
      	};
      	
      	protected:
      	Node * _pHead;
      	Node * _pTail;
      	
      	
      	public:
      		DLink2(int num_elements);
      		DLink2(int num_elements,T * element_array);
      		DLink2();
      		~DLink2();
      		
      		Node * Link(Node * lastlink,bool before);	
      		Node * Link(Node * lastlink,T value,bool before);
      		
      		void InsertEnd(T value,bool before);
      		
      		template <typename T>
      		friend std::ostream & operator<<(std::ostream & os, 
      		const DLink2<T> * dlink);
      };
      The definitions follow in the same file... there is a separate main.cpp where I instantiate two objects and output them via cout.

      Thanks again.

      Comment

      • boxfish
        Recognized Expert Contributor
        • Mar 2008
        • 469

        #4
        Try this:
        Code:
        friend std::ostream & operator<< <> (std::ostream & os, const DLink2<T> * dlink);
        I don't know what the pair of angle brackets means, but hopefully they will make it compile.

        Comment

        • JonathanS
          New Member
          • Jan 2008
          • 37

          #5
          DM seems to take either the way I specified above (with the template <typename T> immediately before the friend declaration) or the way you have proposed with the two angle brackets in the middle.

          g++ doesn't balk about the DLink2<T>::Node in the return type anymore but balks when I declare DLink2<T>::Node in the ostream << friend function (along with DLink2<T>::_pHe ad and _pTail (which I've declared as protected). Not sure if I'm still missing something.

          P.S. could someone explain the notation with the empty angle brackets after the function to me
          Last edited by JonathanS; Dec 23 '08, 10:59 PM. Reason: Added P.S.

          Comment

          • JonathanS
            New Member
            • Jan 2008
            • 37

            #6
            Sorry to double post

            I've added in the change that boxfish suggested, and I think that I'm still having some problems with the template business overall as compiling under g++ still gives me the following error:

            LOCALS~1\Temp/ccGyaaaa.o(.tex t$_ZN6DLink2IiE C1EiPi[DLink2<int>::
            DLink2(int, int*)]+0x1b0): In function `ZSt17__verify_ groupingPKcjRKS s':
            c:/mingw/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/locale_
            facets.tcc:2510 : undefined reference to `DLink2<int>::L ink(DLink2<int> ::Node*, i
            nt, bool)'
            LOCALS~1\Temp/ccGyaaaa.o(.tex t$_ZN6DLink2IiE C1Ei[DLink2<int>::DL
            ink2(int)]+0x173):c:/mingw/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/
            3.4.2/bits/locale_facets.t cc:2510: undefined reference to `DLink2<int>::L ink(DLi
            nk2<int>::Node* , bool)'
            collect2: ld returned 1 exit status

            Anyhow, I'm thinking there is still some underlying problem as it is reporting those errors in the main function (the template class is declared and defined in a separate header file).

            Comment

            • weaknessforcats
              Recognized Expert Expert
              • Mar 2007
              • 9214

              #7
              The code from the OP post #16 compiles and links using Visual Studio.NET 2008.

              Comment

              • JonathanS
                New Member
                • Jan 2008
                • 37

                #8
                Not sure what OP#16 refers to, but I am also wondering why g++ is saying these functions are undefined once I get to main(). Could this be a specific problem with the compiler?

                Thanks and happy holidays to all.

                Comment

                • weaknessforcats
                  Recognized Expert Expert
                  • Mar 2007
                  • 9214

                  #9
                  OP #16 refers to the Original Poster (that's you) and Post #16 (in the upper right corner).

                  Comment

                  • weaknessforcats
                    Recognized Expert Expert
                    • Mar 2007
                    • 9214

                    #10
                    Actually, I screwed that up. The site has change3d the posting format. I should have said OP #3. The 16 was the OP number of posts.

                    Sorry.

                    Comment

                    • JonathanS
                      New Member
                      • Jan 2008
                      • 37

                      #11
                      Clarification of differences?

                      So, is this case something that DM is letting go that it shouldn't or an enforcement by gcc that shouldn't be in place?

                      Also, why the <> after the function name (operator<< in this case)?

                      Comment

                      • weaknessforcats
                        Recognized Expert Expert
                        • Mar 2007
                        • 9214

                        #12
                        When you have a function template the compiler needs to know what type to substitute use when it makes its copy of the template. Usually this is done by looking at the function arguments. However, it can happen that none of the arguments are a parameterized type and this lack requires a means to tell the compiler what type to substitute. Therefore, you code MyFunct<int>() to pass this info to the compiler. You already do this for class variables so the syntax is consistent with that.

                        Comment

                        Working...