Click here to Skip to main content
15,885,244 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I get some compiling errors about template instantiation , but I can't find where the syntax errors happens. Can some help me?


C++
template<typename Type> class SingleList;

template<typename Type> class SingleListNode{
private:
    friend class SingleList<Type>;

    SingleListNode() : next(NULL){}

public:
    friend ostream& operator<< <Type>(ostream& os,SingleListNode<Type>& sln);                  //Error!!!

private:
    SingleListNode *next;
};

template<typename Type> ostream& operator<<(ostream& os,SingleListNode<Type>& out){
    os<<out.data;
    return os;
}

template<typename Type> class SingleList{
public:
    SingleList()
        {
            head =  new SingleListNode<Type> () ;                 //Error!!!
        }
    ~SingleList(){
        delete head;
    }

private:
    SingleListNode<Type> *head;
};


Compiler error message:
|| g++ -g -I ./inc/ -c single_list_test.cpp  -o single_list_test.o
|| single_list.h: In instantiation of ‘SingleListNode<int>’:
single_list.h|25 col 13| instantiated from ‘SingleList<Type>::SingleList() [with Type = int]’
single_list_test.cpp|9 col 18| instantiated from here
single_list.h|10 col 18| error: template-id ‘operator<< <int>’ for ‘std::ostream& operator<<(std::ostream&, SingleListNode<int>&)’ does not match any template declaration
|| make:
*** [single_list_test.o] Error 1


[Edit: code-tags fixed]
Posted
Updated 13-May-12 16:44pm
v2
Comments
«_Superman_» 13-May-12 22:27pm    
The code as you've posted is fine.
Please post the code where the class template is being called.
915086731 14-May-12 0:18am    
#include "single_list.h"
int main()
{
SingleList < int > list; //The template is called here, very simple!!!
return 0;
}
«_Superman_» 14-May-12 0:50am    
I use Visual Stdio and it compiles just fine.
No Error.

Seems to work in Visual Studio, so I can't say for sure what's the problem.

However, I've found that friend declarations involving templates can be quite tricky to declare correctly. (used to be near impossible in older versions of VS) On occasion I fixed these problems by declaring a helper class instead: That helper class would have a single public constructor with the same parameter list as the function in question, and it would be declared friend to the original templated class. In your case it would be sth. like this:
template <typename Type> class SingleList;
template <typename Type> class SingleListNode;
template <typename Type> class SingleListNodeStreamHelper {
   ostream& os;
   SingleListNode<Type>& node;
public:
   SingleListNodeStreamHelper(ostream& s, SingleListNode& n)
    : os(s), node(n) {}
   ostream& operator()(); {
      // do some streaming ...
      return os;
   }
};

// SingleList declared here ...

template <typename Type> class SingleListNode {
private:
   friend SingleListNodeStreamHelper<Type>; // new!

   // rest of class declaration ...
};
// stream function now does not need to be friend!
ostream& operator<< <Type>(ostream& s, SingleListNode<Type> n) {
    SingleListNodeStreamHelper<Type> helper(s, n);
    return helper();
}


I haven't taken the time to test this, but I hope you understand the principle anyway.
 
Share this answer
 
v2
The zeroth thing to do with template problems...

Grab the latest compiler you can.

The first thing to do with any template instantiation problems...

Get rid of the template. Now I know this sounds weird but if you replace hard-code <t> everywhere the compiler might give you an idea of anything you're doing that sounds a bit fishy to it. And make sure you compile on the highest warning level possible - which might mean you get even more inexplicable messages from the template but it's worth a go.

The second thing is to bin any friend and forward declarations. FREX why does a list node need to know about the thing it's contained in and vice-versa? Lists append to the telling the node currently at the end that there's a new node, hang onto it. It might not tell you where the instantiation's going wrong but it might get the code moving again.

The third thing is to try something like Stefan's suggested. C++98 and '03 are full of places templates don't work as you'd expect them AND compilers have varying degrees of standard compliance. If you're feeling particularly brave have a look in you compiler's standard library to see the dirty tricks it has to pull off to get something working.

Cheers,

Ash


Cheers,

Ash
 
Share this answer
 
Comments
stib_markc 15-May-12 7:05am    
correct 5+
915086731 26-May-12 0:30am    
Thanks very much.
Try to add the following two lines (deferred declarations):

C++
template<typename Type> class SingleListNode;
template<typename Type> ostream& operator<<(ostream& os,SingleListNode<Type>& out);

template<typename Type> class SingleListNode{
 
Share this answer
 
v2
XML
To my gcc , just modify the following statement


    friend ostream& operator<< <Type>(ostream& os,SingleListNode<Type>& sln)
to

     friend ostream& operator<< (ostream& os,SingleListNode<Type>& sln)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900